简体   繁体   中英

angular calling an utility function from $rootScope in a filter

I have a utility function notNull() intended to be used with filters like so:

 ...| filter:notNull()"

I need it in more directives and that's why I placed it in $rootScope.

The problem is that my filter isn't called.I created a sample plnkr:

http://plnkr.co/edit/Nq0iLw?p=preview

Can someone help? why isn't the filter called and not filtering my items?

PS. this expression in the filter doesn't seam to work for nulls :

 ...| filter:{myProp:!null}

[ Note : Updates arranged in reverse chronological order.]

UPDATE 2

First, to answer your question "why does ...| filter:{myProp:!null} not work:
It is because the syntax you are trying to use is (according to the docs ) applicable only to string values (and null is not a string value).

You could create (and attach to your app) a custom filter:

app.filter("notEqual", function() {
    return function(items, key, value) {
        var filtered = [];
        items.forEach(function(item) {
            if (item && (item[key] !== undefined) 
                    && (item[key] !== value)) {
                filtered.push(item);
            }
        });
        return filtered;
    };
});

Then use it from any directive like this:

...| notEqual:'<keyName>':<valueToCompareAgainst>

Eg:

app.directive("mytag", function() {
    return {
        restrict: "E",
        template: "<div ng-repeat=\"item in myModel | notEqual:'a':null\">"
                + "    item: {{item}}"
                + "</div>",
        scope: {
            myModel: "="
        }
    };
});

See, also, this other other short demo .


UPDATE

It might be a better idea to use a service or a factory for utility methods that should be available to many controllers/scopes and should be customizable. Eg:

app.factory("notNullFactory", function() {
    var factory = {};
    factory.notNull = function(caption) {
        return function(item) {
            console.log(caption + " " + JSON.stringify(item));
            return (item !== null);
        };
    };
    return factory;
});

Now, you can use notNullFactory 's notNull(...) function to create customizable filter-functions:

app.directive("mytag", function(notNullFactory) {
    return {
        restrict: "E",
        template: "<div>"
                + "    <div ng-repeat=\"item in myModel | filter:notNull('Checking')\">"
                + "        item: {{item}}"
                + "    </div>"
                + "</div>",
        scope: {
            myModel: "="
        },
        link: function($scope) {
            $scope.notNull = function(caption) {
                return notNullFactory.notNull(caption);
            };
        }
    };
});

See, also, this other short demo .


It is not that your filter isn't called, rather it is not defined. At the time you define $scope.notNull , setting it equal to $rootScope.notNull , the latter is undefined .

Instead, you could get rid of the link property and use:

...| filter:$parent.notNull()...

See, also, this short demo .

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