12

簡単な式バインディングを介してコントローラーメソッドによって返された値を表示するAngularアプリケーションがあります。

<div>{{getValue()}}</div>

問題のメソッドが値を返すだけの場合、メソッドは 2 回呼び出されますが、これは非常に奇妙です。

$scope.getValue = function(){
  return 'some value';
}

ただし、メソッドがサーバーからファイルを取得するなどの非同期処理を行う場合、コードは無限ループに入ります。

$scope.getValueAsync = function(){
  $http.get('myfile.html')
    .success(function (data, status, headers, config) {
      return 'some async value';
    });

  return 'file not found'; // same value returned every time but $digest cycle still loops
}

私はAngularを初めて使用するので、おそらくここで基本的なことを見逃していますが、何が起こっているのか説明してもらえますか?

プランカー

これはhttp://plnkr.co/7BriYDbdVJvIoIigQcTUで遊ぶプランカーです

4

2 に答える 2

17

非同期関数は毎回まったく同じ文字列を返しますが、関数は $http サービスで ajax 呼び出しも行うため、$digest サイクルがループで発生します。

$rootScope.$apply() リクエストが完了すると$http サービスが$applyトリガーされ、 $digest サイクルがトリガーされるため、ビュー式が再評価され、その代わりに非同期関数が再度呼び出されます...

app.controller('MainCtrl', function($scope, $http) {

  $scope.getValue = function(){
    return 'some value';
  }

  $scope.getValueAsync = function(){
    $http.get('myfile.html')
      .success(function (data, status, headers, config) {
        return 'some async value';
      });

    return 'file not found';
  }
});
<div>{{getValueAsync()}}</div>

教訓: 式で関数を使用する場合は、関数が $digest ループをトリガーする外部の何かに影響を与えないようにし、同じ入力に対して関数が常に同じ出力を返すようにします。

于 2013-07-04T10:59:09.260 に答える