2

私はAngularJSを初めて使用するので、これは実際にはまだ完全には理解していないコアコンセプトを示している可能性があります。$qpromiseオブジェクトを使用して、「リモートデータ」をローカルデータのように処理しようとしています。リモートデータがフェッチされないときまで、promiseオブジェクトは解決されませんが、解決されたらすぐに、ビュー内のすべての依存データバインディングを更新する必要があります。ただし、次のアプローチでは、前の呼び出しで解決されたpromiseオブジェクトが生成されたremote_total場合でも、が繰り返し呼び出される無限ループが発生します。remote_total

これが私の見解です

<div ng-controller="MyController">
  {{ remote_total() }}
</div>

コントローラからの関連スニペットは次のとおりです。

function MyController($scope, $q, $http) {
  $scope.remote_total = function() {
    var def = $q.defer();
    $http.get('/my/remote/service.json').success(function(data) {
      def.resolve(data);
    });
    return def.promise;
  }
}

まず、なぜこれが無限ループに陥っているのかを誰かが私に説明できれば素晴らしいと思います。第二に、私がやろうとしていることを達成するための最良の方法は何ですか?

4

2 に答える 2

5

注: Angular 1.2+ については、以下の更新を参照してください。

$q実際、AngularJSによって認識されるというAngularJS の約束 (提供) は興味深いものです。そしてもう一つは連鎖可能です!

だからあなたのコードでは、あなたはただ行うことができます

$scope.remote_total = $http.get('/my/remote/service.json').then(function(data) {
  return data;
});

および表示のみ<div>{{remote total}}</div>(注:機能ではなく、値のみ)。

そして、AngularJS は自動的にその promise を認識し、$http.get promise を解決してから、関数にチェーンし、結果の値をテンプレートに入れます。

それで全部です :)

更新: Promise の自動デラップは、AngularJS 1.2 ではデフォルトで無効になっており、1.3 では完全に削除されます。

動作するコード:

$http.get('/my/remote/service.json').then(function(response) {
  $scope.remote_total = response.data;
});
于 2013-01-21T23:06:56.567 に答える
3

Angular はダーティ チェックを実行して 2 ウェイ バインディングを実現します。各サイクルで、監視されているプロパティの以前の値を保存し、それを新しい値と比較します。そのプロパティが関数の場合、それが呼び出され、結果が比較されます。

監視する関数を配置しましたが、各サイクルで関数が呼び出されているため、http リクエストが発生します。

あなたがしたいことは、promise を独自に作成し、その promise を監視 (または表示) のスコープにアタッチすることです。

また、$http サービスは既に promise を返しているため、別の promise を作成する必要はありません。

function MyController($scope, $q, $http) {
  $scope.getRemoteTotal = function() {
    var def = $http.get('/my/remote/service.json').then(function(response) {
      $scope.remoteTotal = response.data;
    });
  }
  $scope.getRemoteTotal();
}

.

<div ng-controller="MyController">
  {{ remoteTotal }}
</div>
于 2013-01-21T06:43:16.593 に答える