AngularJS-ngRepeatでフィルタリングされた結果参照を取得する方法


129

私はそのようなフィルターでng-repeatディレクティブを使用しています:

ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4"

レンダリングされた結果を細かく見ることができます。次に、コントローラーでその結果に対していくつかのロジックを実行したいと思います。問題は、結果アイテムの参照を取得するにはどうすればよいですか?

更新:


明確にするために:私はオートコンプリートを作成しようとしています、私はこの入力を持っています:

<input id="queryInput" ng-model="query" type="text" size="30" placeholder="Enter query">

そしてフィルタリングされた結果:

<ul>
   <li  ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4">{{item.name}}</li>
</ul>

次に、結果をナビゲートして、アイテムの1つを選択します。

回答:


270

更新:これは、以前より簡単な方法です。

 <input ng-model="query">
 <div ng-repeat="item in (filteredItems = (items | orderBy:'order_prop' | filter:query | limitTo:4))">
   {{item}}
 </div>

その後$scope.filteredItems、アクセス可能です。


返信いただきありがとうございます。最新情報をご覧ください。どのようにそれを実装しますか?私はinitでアイテムリスト全体を取得します
Shlomi Schwartz 2012

とてもクールです。ありがとうございます。それがNGの組み込み機能だったらいいのに
Shlomi Schwartz '30 / 07/30

3
このアプローチの問題は、割り当てられたプロパティを監視すると、$ digests(イテレーションごとに1つ)にスパムを送信することになることです...多分これを回避するいくつかの方法があるでしょうか?
JuhoVepsäläinen2013

1
検索オブジェクトとconsole.logを監視すると、filteredItems常に1つのフィルターでデータが取得されます。これは、変更されたばかりのフィルターの結果ではなく、前の変更の結果です。何か案は?
ProblemsOfSumit

4
誰かが私を説明できますか、なぜこれはうまくいくのですか?$ scopeの変数は繰り返しスコープ(スコープの継承)でアクセスできることを理解できますが、その逆はどうでしょうか?どうやって?いくつかのドキュメントをいただければ幸いです。ありがとう
dalvarezmartinez1

30

これが、Andy Joslinのソリューションのフィルターバージョンです。

更新:重大な変化。バージョン1.3.0-beta.19(このコミット)以降、フィルターにはコンテキストがなくthis、グローバルスコープにバインドされます。コンテキストを引数として渡すか、ngRepeatの新しいエイリアス構文1.3.0-beta.17 +を使用できます。

// pre 1.3.0-beta.19
yourModule.filter("as", function($parse) {
  return function(value, path) {
    return $parse(path).assign(this, value);
  };
});

// 1.3.0-beta.19+
yourModule.filter("as", function($parse) {
  return function(value, context, path) {
    return $parse(path).assign(context, value);
  };
});

次にあなたの見解で

<!-- pre 1.3.0-beta.19 -->
<input ng-model="query">
<div ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4 | as:'filteredItems'">
 {{item}}
</div>

<!-- 1.3.0-beta.19+ -->
<input ng-model="query">
<div ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4 | as:this:'filteredItems'">
 {{item}}
</div>

<!-- 1.3.0-beta.17+ ngRepeat aliasing -->
<input ng-model="query">
<div ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4 as filteredItems">
 {{item}}
</div>

これにより、にアクセスできます$scope.filteredItems


ありがとう!フィルターコードがどのように機能するかを説明できますか?私は$ parseに精通していません。角度のドキュメントは、フィルターがどのように機能するかをデコードするのに役立ちませんでした。
Magne、2014

2
@マグネ問題ありません!更新を確認してください。痛みや苦痛を和らげるのに役立ちます。簡単に言えば、あなたの質問に答えるの$parseは、Angularの式コンパイラです。たとえば、文字列 'some.object.property'を取り、指定されたパスで指定されたパスの値を設定または取得できる関数を返します環境。具体的には、ここで$ scopeにフィルター結果を設定するために使用しています。これがあなたの質問に答えてくれることを願っています。
kevinjamesus86 2014年

23

このようなものを試してください、ng-repeatの問題は、アクセスできないために子スコープを作成することです

フィルターアイテム

コントローラから

<li ng-repeat="doc in $parent.filteritems = (docs | filter:searchitems)" ></li>

16

更新:

1.3.0以降でも。コントローラまたは親のスコープに配置する場合は、as構文を使用しそれを行うことはできません。たとえば、次のコードがあるとします。

<div>{{labelResults}}</div>
<li ng-repeat="label in (labels | filter:query | as labelResults)">
</div>

上記は動作しません。それを回避する方法は、$ parentを次のように使用することです。

<li ng-repeat="label in ($parent.labelResults = (labels | filter:query))">

これにlimitToフィルターがある場合は注意してください。$ parent.labelResultsには反映されません
Zack

console.log labelResultsがいつもデータを1つのフィルターで後で取得する場合。これは、変更されたばかりのフィルターの結果ではなく、前の変更の結果です。この問題はありませんでしたか?
アンナ

10

Andyのソリューションのやや良いバージョンを思いつきました。彼のソリューションでは、ng-repeatは割り当てを含む式にウォッチを配置しています。各ダイジェストループはその式を評価し、結果をスコープ変数に割り当てます。

このソリューションの問題は、子スコープ内にいる場合に割り当ての問題が発生する可能性があることです。これは、 ng-modelでドットを使用

このソリューションについて私が気に入らないもう1つの点は、フィルター処理された配列の定義がビューマークアップのどこかに埋め込まれていることです。ビューまたはコントローラーの複数の場所で使用すると、混乱する可能性があります。

より簡単な解決策は、割り当てを行う関数のコントローラーに時計を置くだけです。

$scope.$watch(function () {
    $scope.filteredItems = $scope.$eval("items | orderBy:'order_prop' | filter:query | limitTo:4");
});

この関数は各ダイジェストサイクル中に評価されるため、パフォーマンスはアンディのソリューションと同等です。また、関数に任意の数の割り当てを追加して、ビューの周りに散在させるのではなく、すべてを1つの場所に保持することもできます。

ビューでは、フィルターされたリストを直接使用するだけです。

<ul>
    <li  ng-repeat="item in filteredItems">{{item.name}}</li>
</ul>

これは、これがより複雑なシナリオで示されているフィドルです。


超きれいで、構造を汚染しません、いいですね!
kuzyn 2016年

この解決策は、ngのrepeat..thatsの代わりにイオン性のコレクションの繰り返しを使用していたme..iに最適ですなぜ私のために受け入れられた回答のdidntの仕事
Lakshay

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.