2009-11-02 10 views

ответ

1

Не уверен, что, если выполнены следующие работы, но это может быть решение:

MyDomainClass.metaClass.origSave = MyDomainClass.metaClass.save 
MyDomainClass.metaClass.save = {-> 
    delegate.extraSave() 
    delegate.origSave() 
} 

Пожалуйста, дайте мне feedbeck если выше работал ...

+0

Пробовал, что вчера. Не работает, говоря, что 'origSave' является свойством метакласса или чем-то, а не закрытием, что-то вроде этого. Пробовал разные способы его называть: 'origSave()' и 'origSave.call()' – Archer

+1

Исправить код здесь: http://stackoverflow.com/a/8388366/207791 –

4

Прежде всего , Bootstrap.groovy не может быть лучшим местом для такого метапрограммирования. Проблема с этим подходом заключается в том, что изменения в классах будут применяться при запуске приложения, но вы можете потерять эти изменения, когда приложение будет перезагружено. Очевидно, что это только проблема во время разработки, а не проблема вообще, если вы не против перезапуска сервера каждый раз, когда вы вносите изменения, но я бы сказал, что это быстро станет серьезным раздражением. Чтобы изменения были применены при перезагрузке приложения, вы должны переместить метапрограммирование в плагин, где вы можете подключиться к событию жизненного цикла приложения .

Так шаги:

  • Создать плагин
  • Сделайте метапрограммирование в doWithDynamicMethods и onChange закрытия плагина дескриптора

Вот полный пример, где я «переопределить» chain() на всех классах контроллера. Код, аналогичный для метода save() для классов домена, должен содержать только некоторые очевидные замены, например. использовать application.domainClasses вместо application.controllerClasses

def doWithDynamicMethods = {ctx -> 

    application.controllerClasses.each {controller -> 
     replaceChain(controller) 
    } 
} 

def onChange = {event -> 
    if (application.isArtefactOfType(ControllerArtefactHandler.TYPE, event.source)) { 
     def clz = application.getControllerClass(event.source?.name) 
     replaceChain(clz) 
    } 
} 

private replaceChain(controllerClass) { 

    // Save a reference to the grails chain() method 
    def grailsChain = controllerClass.metaClass.pickMethod("chain", [Map] as Class[]) 

    controllerClass.metaClass.chain = {Map params -> 

     println "My code to execute before chain goes here" 

     // Invoke the grails chain() method 
     grailsChain.invoke(delegate, [params] as Object[]) 

     println "My code to execute after chain goes here" 
    } 
} 
2

почему не Усиливая Горм события для этой цели? В доменном классе:

def extraSave() { 
    // ... 
} 

def beforeInsert = { 
    extraSave() 
} 

def beforeUpdate = { 
    extraSave() 
} 

ИМХО это более чистый подход. Документация не найдена here

+0

Недостатком этого подхода является то, что вам нужно добавить extraSave() для обработчиков событий каждого класса домена. Подход метапрограммирования потребует только указать/вызывать extraSave() в одном месте –

+0

, но я все же предпочел бы подход на основе EntityInterceptor при работе с такими вещами. Переопределение метода GORM может быть реальной PITA. –

+1

btw. для использования EntityInterceptor просто создайте подкласс org.hibernate.EmptyInterceptor и зарегистрируйте его как bean с именем «entityInterceptor» в вашем grails-app/conf/spring/resources.groovy (так как Grails 1.2 - это возможно и в старой версии , но регистрация перехватчика больше работает) –

 Смежные вопросы

  • Нет связанных вопросов^_^