4

これは、以前のAngularJSの質問のフォローアップです。

このビデオチュートリアルで言及されている$resourceサービスの機能を複製しようとしています:link

このチュートリアルでは、非同期呼び出しを使用してスコープ変数とそのビューを更新できることを示しています。まず、設定されているリソースは次のとおりです。

$scope.twitter = $resource('http://twitter.com/:action',
    {action: 'search.json', q: 'angularjs', callback: 'JSON_CALLBACK'},
    {get: {method: 'JSONP'}});

次に、get関数がリソースで呼び出され、ajax呼び出しが行われ、必要なスコープ変数が更新されます。

$scope.twitterResult = $scope.twitter.get();

ここで起こっていること$scope.twitter.get()は、空のオブジェクト参照をすぐに返すことです。次に、ajaxリクエストが返されると、そのオブジェクトはTwitterからのデータで更新されます。次に、ビューはすべての{{twitterResult}}インスタンスを更新し、返されたデータが表示されます。

オブジェクトが非同期コールバックで更新されたときに、スコープは値が変更されたことをどのように認識しますか?

私はそうは思いません-コールバックはスコープである種の更新関数を呼び出さなければなりませんよね?しかし、もしそうなら、これはどのように行われますか?$applyそれが答えかもしれないという関数を聞いたことがありますが、リソース内から$scope。$apply()をどのように参照しますか?

問題を説明するためにJSFiddleを作成しました:http://jsfiddle.net/Qcz5Y/10/

(編集:これは、setTimeoutの代わりにajax呼び出しを使用して問題を説明するために、異なる非同期呼び出しを備えた新しいJSFiddleです:http://jsfiddle.net/Qcz5Y/14/

この例では、コントローラーとリソースが表示されます。コントローラのスコープにはfruit、オブジェクトに設定された状態から始まるプロパティ、があります。[新しいフルーツを取得]をクリックすると、そのプロパティはに設定されfruitResource.get()、すぐに空のオブジェクトが返されます。次に、非同期呼び出しを行い、最後に、最初に返されたオブジェクトの値を更新するコールバックを実行します。

これが発生すると、の値が$scope.fruitコールバックで設定された値に適切に更新されます。しかし、それはビューに反映されていません。

[現在の果物を印刷]をクリックすると、現在の値がコンソールに記録されます$scope.fruit。これは確認のためだけのものでした。ビューを更新するという副作用があります。

関数の下部で$scope。$apply()のようなことをする必要があるように感じます(get_callbackコードに表示されます)。それは正しいことでしょうか?もしそうなら、どのように私はfruitResource内の$ scopeへの参照を取得しますか?おそらくパラメーターとして渡してその方法で参照できることはわかって$scopefruitResource.get()ますが、上部にある例の$ resource.get()関数はこれを行う必要がないため、AngularJSが何らかの方法を提供することを期待していました。サービスからスコープを自動的に取得します。

ありがとう!

4

2 に答える 2

9

私はあなたがサービスに渡し$rootScopeてそれからそれを呼ぶことができると思いました$apply。したがって、ビューを更新する場合は、を実行するだけです$rootScope.$apply()

更新されたJSFiddleは次のとおりです。http://jsfiddle.net/Qcz5Y/11/

于 2012-08-19T01:38:49.493 に答える
1

実際、Resourceの動作のシミュレーションは非常に単純であり、要約すると、非同期呼び出しを実行して、空の結果をすぐに返します。次に、データがサーバーから到着したときに、返された参照を更新する必要があります。ユースケースを使用した例を次に示します。

   get: function() {
        var fruit = {};

        // Asynchronous call that executes a callback. Simulation of ajax/db request            
        $timeout(function() {
            fruit.type = ['banana', 'strawberry', 'watermellon', 'grape'][Math.floor(Math.random() * 4)];
            fruit.count = [1, 2, 3, 4][Math.floor(Math.random() * 4)];
        }, 2000);

        return fruit;
    } 

完全なjsFiddleは次のとおりです。http://jsfiddle.net/pkozlowski_opensource/sBgAT/1/

$timeoutは必要なときに$applyの呼び出しを処理し、手動の介入なしにUIの再描画をトリガーするため、angularの$timeoutサービスを使用して非同期呼び出しをシミュレートしていることに注意してください。$ applyの呼び出しが必要なsetTimoutを使用しようとしていたため、問題が発生していました。

于 2012-08-19T08:04:07.947 に答える