web-dev-qa-db-ja.com

AngularJS-ngRepeatフィルター結果の参照を取得する方法

私は次のようなフィルターで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つを選択します。

125
Shlomi Schwartz

UPDATE:以前の方法よりも簡単な方法があります。

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

その後、$scope.filteredItemsにアクセスできます。

265
Andrew Joslin

Andy Joslinのソリューションのフィルターバージョンを以下に示します。

更新:変更を壊します。バージョン1.3.0-beta.19( this commit )の時点では、フィルターにはコンテキストがなく、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にアクセスできます。

30
kevinjamesus86

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

フィルターアイテム

コントローラーから

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

更新:

1.3.0の後でも。コントローラまたは親のスコープに配置したい場合は、as構文ではできません。たとえば、次のコードがある場合:

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

上記はnot動作します。それを回避する方法は、$ parentを使用することです:

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

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

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

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

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

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

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

ビューでは、フィルタリングされたリストを直接使用します。

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

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

10
Dave Johnson