6

I need to access data that was already filtered on a template (inside a ng-repeat) from my controller.

Here's what I mean:

I have this table in my template:

 <table class="table">
        <thead>
            <th>Name</th>
            <th>Gender</th>
        </thead>
        <tbody>
            <tr ng-repeat="person in persons | filter:query">
                <td>{{person.name}}</td>
                <td>{{person.gender}}</td>
            </tr>
        </tbody>
</table>

Then I have a <select> that is used to filter data by gender

<h1>Cluster:</h1>
    <select ng-model="query.gender" >
        <option value ="">ALL</option>
        <option value ="male">Male</option>
        <option value ="female">Female</option>
    </select>

This works ok.

If someone selects one of the options, I need to do something with the filtered results. That's why I have a $watch in my controller that looks for changes to the filter query:

$scope.$watch('query.gender', function(newValue, oldValue) {
            // Here is where I need to get filtered results
});

My question is:

How do I access the FILTERED content from the controller?

I'd like this preferably without having to do another "filtering" operation in the controller... (since the data was already filtered, the result is sitting somewhere in memory, right?)

1
  • 1
    I don't think the result is sitting in memory, no. ng-repeat filters the collection and generate a dom element for every accepted person, and that's all. Commented Feb 1, 2014 at 14:19

2 Answers 2

13

You can simplify your code with the following:

    <tbody>
        <tr ng-repeat="person in (filteredPersons = (persons | filter:query))">
            <td>{{person.name}}</td>
            <td>{{person.gender}}</td>
        </tr>
    </tbody>

After that, you can get access to $scope.filteredPersons into controller or {{filteredPersons}} right into the view :)

Sign up to request clarification or add additional context in comments.

2 Comments

this solution looks better to me
obs, sometimes you need to envelop your model to see the right result like object. filteredPersons, object. persons, etc (this way, works to me)
5

I'm not entirely sure, but you can use the filter function in your controller. So try something like:

$scope.$watch('query.gender', function(newValue, oldValue) {
        var x = $filter('filter')($scope.persons, $scope.query);
});

x should then contain the same filtered data as in your table I think. Have a look at the docs here: http://docs.angularjs.org/api/ng.filter:filter for some more info.

6 Comments

The second argument should be $scope.query, not $scope.query.gender
Hmm ok, Just going to do a bit more investigation. I think I wrote the wrong code for using hte $filter function.
Ah ok! Just updated my code again, but I'll revert it back. So it worked with $scope.query?
I guess that if there is no way of getting the already-filtered data from memory, this is the correct answer. I wanted to get the best performance. Thanks a lot!!!
@mylescc: you should also simply manually filter the collection in your controller when a radio button is clicked, and save the result in a scope field, and iterate over this field in ng-repeat. This would avoid the double filtering. But I doubt filtering twi would make any significant performance difference, unless the collection is huge.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.