Grails: как использовать службу с областью запроса в библиотеке тегов?


Я относительно новичок в сообществе Grails, но мне уже нравится то, что может предложить движок. В настоящее время я внедряю библиотеку пользовательских тегов, чтобы легко упростить стандартный дизайн на наших страницах. Однако мне нужен способ вызова вспомогательных функций для служебных целей (например, фильтрация данных) и для хранения метаданных уровня запроса о моих тегах (например, счетчики, отношения родитель/потомок).

Я попробовал два решения:

Во-первых: я создал сервис, установил его сфера "по запросу"

package myapp

class CustomTagService {
    static scope = 'request'
    def data = []

    def add(localData) {
        data.add(localData)
    }
}

Однако, когда я пытаюсь ввести его в мою библиотеку тегов

package myapp

class MyTagLib {
    def customTagService

    def myTag = { attrs, body ->
        customTagService.add(attrs)
    }

}

Движок орет на меня за ссылку на область запроса (после долгого мучительного stacktrace): "область 'request' не активна для текущего потока; рассмотрите возможность определения прокси-сервера с областью действия для этого боба, если вы собираетесь ссылаться на него из синглетона "

Во-вторых: я понимаю, что pageScope доступен мне внутри закрытия тега, и я использовал его раньше. Тем не менее, для структура, которую я хочу, инкапсуляция была бы намного предпочтительнее.

Пожалуйста, дайте мне знать, если я иду по неверному пути. Любые предложения будут очень признательны!
1 3

1 ответ:

Вы не можете использовать ограниченные бобы в синглетных бобах, так как синглетные бобы (включая taglibs) создаются при запуске, когда нет активного запроса. Вместо этого используйте прокси с областью действия (немного сложнее) или просто получите Боб из ApplicationContext для каждого использования во время выполнения, когда есть активный запрос:

package myapp

class MyTagLib {

   def grailsApplication

   def myTag = { attrs, body ->
      customTagService.add(attrs)
   }

   private getCustomTagService() {
       grailsApplication.mainContext.customTagService
   }
}