简体   繁体   中英

Angular toggle filter in ng-repeat

I'm trying to display some data using a ng-repeat . I want to have a filter on the displayed data and when I click on a specific item the filter should be removed. When I click again on that specific item, the filter should be added again.

I've started with an idea, in my view I have:

<ion-item class="row" ng-repeat="t in tickets">
    <div class="col" ng-click="toggleFilter(t.name)">{{t.name}}</div>
</ion-item>

In my controller:

.controller('TicketCtrl', function ($scope, $filter) {
    $scope.toggleFilter = function (name) {
        name = $filter('getSlice')(name);
        alert(name);
    }
});   

When I alert the name it gives the correct filtered item, but it's not updating in the view. I think this has to do something with a child scope of the ng-repeat , but I don't know how to do this with toggling a filter.

Does anyone has any suggestions or a solution to solve this problem?

You would want to keep a track of the state of the row (clicked or not clicked). Ideally you do not want to change the scope property's name.

The following code should work for you

<ion-item class="row" ng-repeat="t in tickets" ng-click="t.clicked=!t.clicked">
    <div class="col" ng-if="t.clicked">{{t.name | getSlice}}</div>
    <div class="col" ng-if="!t.clicked">{{t.name}}</div>
</ion-item>

It's not updating in the view, beacause in $scope.toggleFilter you are modifying a local variable not binded with the view, in that list angular is binded with your $scope.tickets variable so you should modify the binded variable directly to see your changes in the view, you could achive this using the $index iterator variable available when you use ngRepeat https://docs.angularjs.org/api/ng/directive/ngRepeat

The result should be something like this:

-view:

<ion-item class="row" ng-repeat="t in tickets">
    <div class="col" ng-click="toggleFilter(t.name, $index)">{{t.name}}</div>
</ion-item>

-controller:

.controller('TicketCtrl', function ($scope, $filter) {
    $scope.toggleFilter = function (name, index) {
        $scope.tickets[index].name = $filter('getSlice')(name);
        alert(name);
    }   

PS Off topic: I see that you are using ionic framework, if you are going to use ng-repeat in mobile devices the performance is going to be much better if you use the collection repeat directive, mobile devices doesn't perform smooth when you scroll long lists of elements with ng-repeat because de 2 way binding of angular. http://ionicframework.com/docs/api/directive/collectionRepeat/

Keep it simple and create a wrapper:

HTML:

<div ng-app="app">
    <div ng-controller="ctrl">
        <button ng-click="toggleFilter()">Toggle Filter</button><br/>
        <span ng-repeat="item in data | filter:myFilter">
            {{item}}<br/>
        </span>
    </div>
</div>

JS:

angular.module('app',[]).
controller('ctrl', function($scope){
    $scope.data = [1,2,3,4,5,6,7,8,9,10];
    $scope.shouldRunFilter = false;

    $scope.myFilter = function(item){
        if($scope.shouldRunFilter)
        {
            return item > 5;
        }

        return item;
    }

    $scope.toggleFilter = function(){
        $scope.shouldRunFilter = !$scope.shouldRunFilter;
    }
});

JSFIDDLE .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM