6

最新の grails 2.3.0 プロジェクトでは、@Mixin注釈を使用してヘルパー クラスをミックスインし、controllerより DRY に保ちます。

コントローラーの再コンパイルを強制するためにコントローラー内でいくつかの変更を行った場合、ミックスインは機能しています。最初のコンパイル ( grails run-app) の後、ヘルパーは混在していませんMissingMethodException。ヘルパー クラスからメソッドにアクセスしようとしています。

ここに私のヘルパーがありますsrc/groovy

class ProjectHelper {
    def withProject(id, Closure c) {
        def project = Project.get(id)
        if (project) {
            c.call project
        } else {
            flash.message = 'Project not found!'
            render view: 'myView'
            return
        }
    }
}

そして(の1つ)controllerを使用するProjectHelper

@Mixin(ProjectHelper)
class ProjectController {
    def index() {
        withProject params.projectId, {project ->
            // do something with the project
        }
    }
}

アプリを使用して起動してプロジェクトをクリーンアップするgrails cleanと、アクセス後に次のエラーが表示されますproject/index

MissingMethodException occurred when processing request: 
    [GET] /<myApp>/project/
    No signature of method: <myPackage>.withProject() is applicable for argument types: 
    (java.lang.String, <myPackage>.ProjectController$_index_closure1_closure10) values: 
    [1, <myPackage>.ProjectController$_index_closure1_closure10@40d889b5]

いくつかの変更ReportController(例: 1 つのスペースの追加) の後、grails は 2 つのソース ファイルをコンパイルし、メソッドwithProjectを使用できます。アクセスproject/indexは期待どおりに機能します。

ここで何がうまくいかないのですか?それはバグですか、それとも何か見逃していますか?

アップデート

を使用すると、grails.util.Mixin別の例外 ( MissingPropertyException) が発生することがわかりました。混合されたクラス プロパティ (私の場合: flash) (再コンパイル後) で動作している( JIRA のこの問題を参照) へのアクセスがないためです。groovy.lang.Mixin

実行時に手動で再コンパイル/インジェクト/ミックスインする方法はありますか?それとも、問題が修正されるまで、パーツgroovy.lang.Mixinの別のエラー処理を見つける必要がありますか?else

助言がありますか?

4

2 に答える 2

2

MissingMethodExceptionミックスインを使用して同様のコード再利用パターンに従っているときに、私は定期的に同じ問題に遭遇していました。

私の場合、に変更groovy.lang.Mixinするgrails.util.Mixin(より具体的にはgrails.util.Mixin、コントローラーにインポートを追加する) ことで、問題は完全に解決されました。

コントローラー変数にアクセスできないということに関しては、 GRAILS-9905が解決されるのを待つことになるかもしれません。ただし、欠陥に関する議論にいくつかの推奨される回避策がリストされていることに注意してください。

于 2014-02-07T17:04:11.823 に答える
1

Mixin最終的にうまくいった回避策は、コントローラーコンストラクターに手動で挿入することでした:

import com.example.MyMixin

class SomethingController {
  def SomethingController() {
    SomethingController.metaClass.mixin(MyMixin)
  }
}
于 2014-04-02T16:15:10.567 に答える