Question

I've been cleaning up an external JSON URL feed that I am using, and I have successfully removed unnecessary special characters via a filter as so:

angularJS.filter('removeChar', function(){
    return function(text) {
        text = text.replace(/\[[^\]]+\]/g, ''); // Characters inside Brackets
        return text.replace(/\;.*/, ''); // Characters after Colon
    };
});

<span ng-bind-html-unsafe="item | removeChar">{{item}}</span>

However, what I am trying to achieve now - is to remove an ng-repeat item if it contains a specific string via a filter I can use.

For example:

<div ng-repeat="item in items | removeItem">{{item['flowers']}}</div>

If the item contains the word 'Red' or 'Green'

<div>Blue Roses</div>
<div>Red Roses</div>
<div>Orand and Green Roses</div>
<div>Yellow Roses</div>
<div>Red and Green Roses</div>

Only this will display from the ng-repeat with the filter:

<div>Blue Roses</div>
<div>Yellow Roses</div>

Help with an example would greatly be appreciated.

Thanks! Roc.

Was it helpful?

Solution

You can use a filter along with the ! predicate that negates the search string:

div ng-repeat="item in items | filter:'!Red' | filter: '!Green'">{{item['flowers']}}</div>

So filter:'!Red' removes anything that does have the string "Red" in it. Those results are passéd to filter: '!Green' which removes any results that have the string "Green" in them.

Here's the relevant docs: http://docs.angularjs.org/api/ng.filter:filter

Performance Update

I was curious about the cost of filtering so I did this jsperf: http://jsperf.com/angular-ng-repeat-test1/2

I created 1,000 strings (items) and then did 4 tests with the following results on my system:

1) Display all 1000 using DI 281,599 ops/sec

  {{items}}

2) Display all 1000 using ng-repeat (no-filter): 209,946 ops/sec 16% slower

  <div ng-repeat="item in items"> {{item}}</div>

3) ng-repeat with one filter 165,280 ops/sec 34% slower

  <div ng-repeat="item in items | filter:filterString1"> {{item}}</div>

4) ng-repeat with two filters 165,553, ops/sec 38% slower

  <div ng-repeat="item in items | filter:filterString1 | filter:filterString2"> {{item}}</div>

This is certainly not a scientific test- I didn't do any controls and it's possible for things like caching to have influenced the results. But I think the relative performance is interesting.

OTHER TIPS

You can use any function available in the current scope as the argument of filter. So you could write something like this, for example.

HTML:

<div ng-app="" ng-controller="FooCtrl">
    <ul>
        <li ng-repeat="item in items | filter:myFilter">
            {{item}}
        </li>
    </ul>
</div>

JS:

function FooCtrl($scope) {
    $scope.items = ["foo bar", "baz tux", "hoge hoge"];

    $scope.myFilter = function(text) {
        var wordsToFilter = ["foo", "hoge"];
        for (var i = 0; i < wordsToFilter.length; i++) {
            if (text.indexOf(wordsToFilter[i]) !== -1) {
                return false;
            }
        }
        return true;
    };
}

Here is a working Fiddle. http://jsfiddle.net/2tpb3/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top