Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS - how to get an ngRepeat filtered result reference

People also ask

How do I get an index value in ng-repeat?

Note: The $index variable is used to get the Index of the Row created by ng-repeat directive. Each row of the HTML Table consists of a Button which has been assigned ng-click directive. The $index variable is passed as parameter to the GetRowIndex function.

Can you tell me what filters are used for in angular?

AngularJS Filters allow us to format the data to display on UI without changing original format. Filters can be used with an expression or directives using pipe | sign. Angular includes various filters to format data of different data types.

How do I filter in NG-repeat?

The ng-repeat values can be filtered according to the ng-model in AngularJS by using the value of the input field as an expression in a filter. We can set the ng-model directive on an input field to filter ng-repeat values.


UPDATE: Here's an easier way than what was there before.

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

Then $scope.filteredItems is accessible.


Here's the filter version of Andy Joslin's solution.

Update: BREAKING CHANGE. As of version 1.3.0-beta.19 (this commit) filters do not have a context and this will be bound to the global scope. You can either pass the context as an argument or use the new aliasing syntax in 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);
  };
});

Then in your view

<!-- 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>

Which gives you access to $scope.filteredItems.


Try something like this, the problem with the ng-repeat is that it creates child scope because of that you can't access

filteritems

from the controller

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

Update:

Even after 1.3.0. if you want to put it on the scope of the controller or the parent you cannot do that with as syntax. For example if I have the following code:

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

the above will not work. The way to go around it is using the $parent as so:

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

I came up with a somewhat better version of Andy's solution. In his solution ng-repeat places a watch on the expression that contains the assignment. Each digest loop will evaluate that expression and assign the result to the scope variable.

The problem with this solution is that you might run into assignment issues if you are in a child scope. This is the same reason why you should have a dot in ng-model.

The other thing I don't like about this solution is that it buries the definition of the filtered array somewhere in the view markup. If it is used in multiple places in your view or your controller it can get confusing.

A simpler solution is to just place a watch in your controller on a function that makes the assignment:

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

This function will be evaluated during each digest cycle so performance should be comparable with Andy's solution. You can also add any number of assignments in the function to keep them all in one place rather than scattered about the view.

In the view, you would just use the filtered list directly:

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

Here's a fiddle where this is shown in a more complicated scenario.