8

外部ソースからデータを取得するファクトリがあります。データを取得したらすぐに、2 番目のファクトリを使用して特定の基準でフィルター処理します。

ファクトリ プロパティはスコープに割り当てられます。

工場でこれを行うと、スコープが更新されません。

factory.foo = [{id:1,name:'foo'}]; // doesn't work

そのため、2 番目の工場でのフィルター処理も機能しません

factory.foo = Filter.filter(); // doesn't work

これが機能している間:

factory.foo.push({id:1,name:'foo'}); // works

これが意図されているかどうか、なぜこのようなものなのか、そしてそれを解決する方法を知っている人はいますか?

完全なサンプルと plunkr

app.factory('Foo',function(Filter) {
  var factory = {
    foo:[],
    getDataForFoo:function() {
      factory.foo = Filter.filter(); // doesn't work
      //factory.foo = [{id:1,name:'foo'},{id:1,name:'foo'}]; // doesn't work
      //factory.foo.push({id:1,name:'foo'}); // works
    }
  };
  return factory;
});

app.factory('Filter',function() {
  var factory = {
    filter:function() {
      var arr = [];
      arr.push({id:1,name:'foo'});
      return arr;
    }
  }
  return factory;
});

app.controller('MainCtrl', function($scope,Foo) {
  $scope.test = 'running';
  $scope.foo = Foo.foo;

  $scope.click = Foo.getDataForFoo;
});

プランカー

4

2 に答える 2

12

問題は、工場で参照が に置き換えられることFactory.fooです。スコープが初期化$scope.fooされると、配列 (空) への参照が保持されます。を呼び出すとFoo.getDataForFoo、参照が内部的に変更されFactory.fooますが、スコープは以前の配列への参照を保持しています。これがpush、配列参照ではなく配列の内容を変更するため、使用が機能する理由です。

これを修正するにはいくつかの方法があります。さまざまなオプションをすべて使用することなく、最も簡単な方法は、関数でラップ$scope.fooして、 を返すことFactory.fooです。このようにして、Angular はダイジェスト サイクルで参照の変更を検出し、それに応じてビューを更新します。

app.controller('MainCtrl', function($scope,Foo) {
  $scope.test = 'running';
  $scope.foo = function() { return Foo.foo };

  $scope.click = Foo.getDataForFoo
});

// And in the view (the relevant part)

<ul ng-repeat="elem in foo()">
  <li>{{elem.id}} {{elem.name}}</li>
</ul>
<a href="" ng-click="click()">add</a>
于 2013-09-02T09:22:21.163 に答える
1

@ Simon-Belangerの答えは正しく、実行可能な解決策を提示しています。

もう 1 つのオプションは、新しい配列を割り当てて参照をリセットするのではなく、単に配列を空にして新しい項目をそこにプッシュすることです (たとえば、更新イベントの場合)。length: に割り当てることで配列を切り捨てることができmyArray.length = 0ます。次に、新しいコレクションを反復処理して、新しいエントリを設定できます。array.push()

于 2014-11-23T21:49:37.520 に答える