2013-09-02 5 views
8

私は、外部ソースからデータを取得しているファクトリを持っています。データを取得するとすぐに、私は第2工場を使用して特定の基準でフィルタリングします。

このプロパティはスコープに割り当てられています。

今、私は私の工場でこれを行うとき、それはスコープを更新しません:

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

そのためにも、この作品つつ、第2工場でfilterinが

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

を動作しません。 :

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

これが意図されている理由は誰か、どのように解決するのですか?

Full Sample plus 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; 
}); 

Plunkr

+3

Simon Belangerの言葉通りです。私はここで説明します:http://angular-tips.com/blog/2013/08/consuming-services/ –

+0

スコープ継承の詳細については、この回答を参照してください。http://stackoverflow.com/questions/14049480/what-スコーププロトタイプのprototypal継承in-angularjs – piatek

+0

@piatek私はスコープの継承に関連しているとは思わない。 –

答えて

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> 
+0

その説明に感謝します。これは良いアプローチですか...それとも、より良い/よりクリーンなプラクティスがありますか? –

+1

これは外部への参照変更を期待するときには良いアプローチです。発見したように、配列の内容を直接(push、spliceなど)変更するか、ファンクションロジックをファクトリに移動することができます(つまり、 'Foo.foo'は配列を返す関数ですが)あなたのテンプレートで 'foo()'を使わなければなりません。もう一つのオプションは 'getDataForFoo'の呼び出しの後に' Foo.foo'を再フェッチすることです: '$ scope.click = function(){Foo.getDataForFoo(); $ scope.foo = Foo.foo; }; '。この時点では、計算されたプロパティ(関数)を使用するかどうかは、実際には優先事項の問題です。 –

+1

私はこれを行う方法の残りの部分を本当に感謝します – user2422960

1

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

もう1つの方法は、新しい配列を割り当てることによって参照をリセットするのではなく、配列を空にして新しい項目を(たとえば、更新イベントのために)押し込むことです。配列を長さ:myArray.length = 0に割り当てて切り捨てることができます。新しいコレクションを繰り返し処理して、新しいエントリを入力することができます。array.push()

+0

私のおかげであなたの考えは良く働いた... +1 :) – Genutek

関連する問題