15

AngularJSのscope。$apply()は、すべてのイベントハンドラー(入力ディレクティブのキーダウン/入力イベント、selectディレクティブの変更イベントなど)およびその他の場合に呼び出されます。

小さな例を参照してください。他のスコープで変更が発生したにもかかわらず、キーを押すたびにngRepeatが再計算され、再描画されるようです。

そのような決定の論理的根拠を知ることは興味深いでしょう。

4

1 に答える 1

17

これについてAngularJSの作成者がいるのは素晴らしいことですが、リピーターでトリガーされた変更は他のスコープ($ rootScopeでさえ)に副作用をもたらす可能性があるため、$ digest()を$rootScopeで呼び出す必要があると思います。

重要なのは、子スコープでトリガーされたメソッドが親スコープのオブジェクトに影響を与える可能性があることです(子スコープは親スコープから継承するため)。したがって、子スコープで定義された関数が親スコープからのオブジェクト参照を変更できない場合でも、親スコープで定義されたオブジェクトの値を変更できます。

上記は少し不可解に聞こえるかもしれませんので、アイテムのリストを含む(少し人工的な)例を考えてみましょう:

$scope.items = [{name: 'foo', value:0}, {name: 'bar', value:0}, {name: 'baz', value:0}];

ここで、ng-Repeatを使用して上記のリストを表示し、アイテムをクリックすると他のアイテムの値がインクリメントされるとしましょう(ここでも、例は少し人工的ですが、ここでのポイントは、1つのスコープでトリガーされたアクションが他のスコープでは副作用があります)。これは次のようになります。

$scope.incOther = function(item) {
        for (var i=0; i<$scope.items.length; i++){
            if ($scope.items[i] !== item){
                $scope.items[i].value++;
            }
        }
    };

サンプル関数は他のスコープの値を変更し、AngularJSは-正しい結果を表示するために-親スコープのウォッチャーを評価する必要があります(オブジェクトが定義された場所がわからないため、$ rootScopeまで)。

これを説明する完全なjsFiddleは次のとおりです。http://jsfiddle.net/pkozlowski_opensource/Z6e5g/3/

実際、上記のjsFiddleには、ウォッチャーの評価が本当に一番上から開始する必要があることを示すために、$rootScopeにオブジェクトも含まれています。

于 2012-09-10T21:32:11.173 に答える