1

現在、プロジェクトを Grails 2.2 から Grails 3.0 にアップグレードする作業を行っており、多くの問題が発生しています。私が現在取り組んでいるのは、Angular $http() とコマンド オブジェクトが正しくデータ バインディングされていないことに関係しています。

現在、Grails はすべての Command オブジェクトを Controller メソッドにバインドします。これはどこでも行われ、すべてを手動でバインドするのは大変な作業になります (私が今思いつく唯一の解決策)。最終的にはこれを行う必要があることはわかっていますが (より多くの制御。Grails は常に正しくバインドされません)、強制されない限り、そうする必要はありません。

class MyController {
    def updateStatus(StatusCommand cmd) {
        println("params: ${params}")
        println("cmd: ${cmd}")

        // example with objectId = 1 being passed in as http() data
        // params will be: objectId: 1
        // cmd will be: cmd.objectId: null
    }
}

以前のソリューションには、request.JSON フィールドを受け取り、params にまだ値がない場合にそれらを params にダンプするインターセプターが含まれていました。

def beforeInterceptor = {
    if (request.JSON) {
        request.JSON?.each { key, value ->
            if (!params[key]) {
                params[key] = value 
            }
        }
    }
}

Grails 3.0 では、Interceptor はコントローラーの外部で個別に定義されるようになったため、以前のものを複製するために以下を作成しました。

class MyInterceptor {
    MyInterceptor {
        matchAll()
    }

    boolean before() {
        if (request.JSON) {
            request.JSON?.each { key, value ->
                if (!params[key]) {
                    params[key] = value 
                }
            }
        }
    }
}

残念ながら、これは以前のように Grails 3.0 では機能しないようです。値は「params」に正しくマップされているように見えますが、コマンド オブジェクトではすべてが null に設定されています。インターセプターが実行される前に、コマンドオブジェクトが「作成」されているとしか思えません。値が request.JSON ではなく params に設定されるため、コマンド オブジェクトは $.ajax() 呼び出しから正しくバインドされます。

インターセプターで作成されたコマンドオブジェクトを手動で設定する方法はありますか、それとも他の解決策のアイデアはありますか?

編集: $http() 角度呼び出しの例

var data = { objectId: 1 };
$http({
    method: 'POST',
    url: myUrl,
    data: data
}).success(function() {
    //stuff
});
4

0 に答える 0