9

私のアプリでは、ページが読み込まれる前に、いくつかの JSON データを取得して配列に割り当てる必要があります。これは、CardService サービスを使用して JSON を取得するための私のコードです。

cards = [];

var cs = {
...
fetchCards: function() {
      var d = $q.defer();
      $http.get("data/cards.php").success(function(data) {
                      cards = data;
                      d.resolve();
                }).error(function(data, status) {
                      d.reject(status);        
                 });
               return d.promise;
      },
getCards: function() { return cards; };
...
}

コントローラーの解決ブロックには、次のものがあります。

WalletController.resolve = {
        getCards: function(CardService) {
                CardService.fetchCards().then(loadView, showError);
        }
}

実際のコントローラーには、次のものがあります。

function WalletController($scope, CardService) {
    $scope.cards = CardService.getCards();
}

問題は、JSON データが cards 変数に割り当てられる前に、サービスの fetchCards 関数が promise を解決しているように見えることです。これにより、数回更新して運が良くなるまで、ビューに空のデータが読み込まれます。

カード変数をコンソールに記録すると、122 行目 (ビューがロードされたとき) で空の配列が取得され、57 行目 (JSON 呼び出しが成功したとき) で完全な配列が取得されるため、ロードの遅延を確認できます。57 行目のコードは、ビューが読み込まれた後に何らかの形で実行されます。

これを修正するにはどうすればよいですか?

4

1 に答える 1

16

私は使用resolveしていませんが、問題がサービスから返された配列へのバインドに関連している場合に備えて、これを捨てています。

サービスから配列を返しcards、UI でそれにバインドする場合は、設定する代わりに同じ配列にデータを入力することをお勧めしますcards = data;(これにより、UI にバインドされていない新しい配列でローカル カードが上書きされます)。

何かのようなもの:

fetchCards: function() {
      var d = $q.defer();
      $http.get("data/cards.php").success(function(data) {
                      cards.length = 0;
                      for(var i = 0; i < data.length; i++){
                          cards.push(data[i]);
                      }
                      d.resolve();
                }).error(function(data, status) {
                      d.reject(status);        
                 });
               return d.promise;
      },

私が説明しようとしているものの実際の例については、このフィドルを参照してください。最初のボタンを複数回クリックするとビューが更新されますが、2 番目のボタンをクリックするとバインドが解除されます。

両者の主な違いは次のとおりです。

  1. 最初のボタンは、元の配列の参照を保持するためにdata.length = 0andを使用しますdata.push()
  2. data2 番目のボタンは、元の配列参照を新しいもので上書きします。data = newArray

更新:また、Mark Rajcok として、次のようにangular.copyを使用して、元の配列の参照を空にしてソースから新しい参照を追加することで、元の配列の参照を保持できます。

fetchCards: function() {
      var d = $q.defer();
      $http.get("data/cards.php").success(function(data) {
                      angular.copy(data, cards);
                      d.resolve();
                }).error(function(data, status) {
                      d.reject(status);        
                 });
               return d.promise;
      },
于 2012-09-05T18:11:35.887 に答える