ng-repeat中未定义属性的AngularJS - filter ?

时间:2022-08-25 09:48:41

For my AngularJS project (v1.2.3), I have a list of routes and am trying to build a navigation bar from the object. What I want to do is display any object with an undefined isRight property in one style, and where the property is defined in another.

对于我的AngularJS项目(v1.2.3),我有一个路由列表,并试图从该对象构建一个导航条。我要做的是用一种样式显示任何带有未定义isRight属性的对象,以及在另一种样式中定义属性的对象。

In one ng-repeat I would like to filter those objects with an undefined isRight property. How can I accomplish this inside the ng-repeat attribute, without having to resort to creating a custom filter function?

在一个ng-repeat中,我想用一个未定义的isRight属性来过滤那些对象。如何在ng-repeat属性中实现这一点,而无需创建自定义过滤器函数?

$scope.nav = [
    { path: '/', title: 'Home' },
    { path: '/blog', title: 'Blog' },
    { path: '/about', title: 'About' },
    { path: '/login', title: 'Login', isRight: true }
];

I realize I could just add the attribute isRight: false to each object, or have separate nav objects for right and left side links, and other such simple workarounds, but I am curious if there is a way to accomplish this with the current structure, using something along the lines of:

我意识到我可以添加属性“染指”:每个对象错误,或有独立的导航对象的权利和左侧链接,和其他这样的简单的解决方法,但我很好奇,如果有一种方法可以做到这一点与当前结构,使用的东西:

<li ng-repeat="link in nav | filter:{isRight:undefined}">

This is more a curiosity than a need, but I appreciate any suggestions.

这与其说是一种需要,不如说是一种好奇,但我很欣赏任何建议。

4 个解决方案

#1


51  

You can negate a filter expression. So instead of dealing with undefined you can just filter out anything where isRight is not (!) true. Like this:

您可以否定一个过滤器表达式。因此,您可以过滤任何isRight为not(!)的内容,而不是处理未定义的内容。是这样的:

<li ng-repeat="link in nav | filter:{isRight:'!true'} ">

And for the opposite you can, of course, do:

相反,你当然可以这样做:

<li ng-repeat="link in nav | filter:{isRight:'true'} ">

demo fiddle

演示小提琴

#2


42  

You can also use <li ng-repeat="link in nav | filter:{isRight:'!'}">

您还可以使用

  • see also How to display placeholders in AngularJS for undefined expression values?

    请参见如何在AngularJS中显示未定义表达式值的占位符?

    var app = angular.module('myApp', [])
    
    app.controller('mainCtrl',['$scope' , function($scope) {
    
    
    $scope.nav = [
        { path: '/', title: 'Home' },
        { path: '/blog', title: 'Blog' },
        { path: '/about', title: 'About' },
        { path: '/login', title: 'Login', isRight: true }
    ];
      
    }])
    <div ng-app="myApp" ng-controller="mainCtrl">
    
    <h3>!isRight</h3>
    <ul>
    <li ng-repeat="link in nav | filter:{isRight:'!'}">{{link.title}}</li>
    </ul>
      
      
    <h3>isRight</h3>
    <ul>
    <li ng-repeat="link in nav | filter:{isRight:'!!'}">{{link.title}}</li>
    </ul>
    </div>
    
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

    #3


    8  

    Edit

    编辑

    I just reread the question, and this is not the answer you are looking for. I will leave it here for documentation purposes, but I do not think there is a way to get the functionality you desire without either building a custom filter or using a custom filter function.

    我只是重读了这个问题,这不是你要找的答案。出于文档的目的,我将把它留在这里,但我认为,如果不构建自定义过滤器或使用自定义过滤器函数,就无法获得所需的功能。

    To expand on why looking for undefined will not work with the default filter we take a look at this code from the AngularJS filter implementation.

    为了详述为什么查找未定义的内容不能使用默认过滤器,我们从AngularJS过滤器实现中查看这段代码。

    switch (typeof expression) {
      ...
      case "object":
        // jshint +W086
        for (var key in expression) {
          (function(path) {
            if (typeof expression[path] == 'undefined') return;
            predicates.push(function(value) {
              return search(path == '$' ? value : getter(value, path), expression[path]);
            });
          })(key);
        }
        break;
      ...
    }
    

    If a value for the filter object's property is undefined, no predicate function is added to the predicates array. In your case you are setting the value of the isRight property to undefined (your filter expression is {isRight:undefined}).

    如果筛选器对象属性的值未定义,则不会向谓词数组添加谓词函数。在您的示例中,您将isRight属性的值设置为undefined(您的过滤器表达式是{isRight:undefined})。

    Original Answer

    原来的答案

    You can always use a predicate function to create arbitrary filters (documentation).

    您总是可以使用谓词函数来创建任意的过滤器(文档)。

    A predicate function can be used to write arbitrary filters. The function is called for each element of array. The final result is an array of those elements that the predicate returned true for.

    谓词函数可以用来编写任意的过滤器。对数组的每个元素调用该函数。最后的结果是谓词返回true的那些元素的数组。

    In your controller create a method to pick the items you want

    在您的控制器中创建一个方法来选择您想要的项目。

    $scope.isRightUndefined = function(item) {
      return item.isRight === undefined;
    }
    

    and change your repeat to be

    把你的重复变成

    <li ng-repeat="link in nav | filter:isRightUndefined">
    

    #4


    4  

    module.filter('notNullOrUndefined', [function () {
        return function (items, property) {
            var arrayToReturn = [];
            for (var i = 0; i < items.length; i++) {
                var test = property !== undefined ? items[i][property] : items[i];
                if (test !== undefined && test !== null) {
                    arrayToReturn.push(items[i]);
                }
            }
            return arrayToReturn;
        };
    }]);
    

    Usage:

    用法:

    <div class="col-md-12" ng-repeat="style in styles | notNullOrUndefined:'background'">
        <span class="ed-item">{{style.name}} Background</span>
    </div>
    

    #1


    51  

    You can negate a filter expression. So instead of dealing with undefined you can just filter out anything where isRight is not (!) true. Like this:

    您可以否定一个过滤器表达式。因此,您可以过滤任何isRight为not(!)的内容,而不是处理未定义的内容。是这样的:

    <li ng-repeat="link in nav | filter:{isRight:'!true'} ">
    

    And for the opposite you can, of course, do:

    相反,你当然可以这样做:

    <li ng-repeat="link in nav | filter:{isRight:'true'} ">
    

    demo fiddle

    演示小提琴

    #2


    42  

    You can also use <li ng-repeat="link in nav | filter:{isRight:'!'}">

    您还可以使用

  • see also How to display placeholders in AngularJS for undefined expression values?

    请参见如何在AngularJS中显示未定义表达式值的占位符?

    var app = angular.module('myApp', [])
    
    app.controller('mainCtrl',['$scope' , function($scope) {
    
    
    $scope.nav = [
        { path: '/', title: 'Home' },
        { path: '/blog', title: 'Blog' },
        { path: '/about', title: 'About' },
        { path: '/login', title: 'Login', isRight: true }
    ];
      
    }])
    <div ng-app="myApp" ng-controller="mainCtrl">
    
    <h3>!isRight</h3>
    <ul>
    <li ng-repeat="link in nav | filter:{isRight:'!'}">{{link.title}}</li>
    </ul>
      
      
    <h3>isRight</h3>
    <ul>
    <li ng-repeat="link in nav | filter:{isRight:'!!'}">{{link.title}}</li>
    </ul>
    </div>
    
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

    #3


    8  

    Edit

    编辑

    I just reread the question, and this is not the answer you are looking for. I will leave it here for documentation purposes, but I do not think there is a way to get the functionality you desire without either building a custom filter or using a custom filter function.

    我只是重读了这个问题,这不是你要找的答案。出于文档的目的,我将把它留在这里,但我认为,如果不构建自定义过滤器或使用自定义过滤器函数,就无法获得所需的功能。

    To expand on why looking for undefined will not work with the default filter we take a look at this code from the AngularJS filter implementation.

    为了详述为什么查找未定义的内容不能使用默认过滤器,我们从AngularJS过滤器实现中查看这段代码。

    switch (typeof expression) {
      ...
      case "object":
        // jshint +W086
        for (var key in expression) {
          (function(path) {
            if (typeof expression[path] == 'undefined') return;
            predicates.push(function(value) {
              return search(path == '$' ? value : getter(value, path), expression[path]);
            });
          })(key);
        }
        break;
      ...
    }
    

    If a value for the filter object's property is undefined, no predicate function is added to the predicates array. In your case you are setting the value of the isRight property to undefined (your filter expression is {isRight:undefined}).

    如果筛选器对象属性的值未定义,则不会向谓词数组添加谓词函数。在您的示例中,您将isRight属性的值设置为undefined(您的过滤器表达式是{isRight:undefined})。

    Original Answer

    原来的答案

    You can always use a predicate function to create arbitrary filters (documentation).

    您总是可以使用谓词函数来创建任意的过滤器(文档)。

    A predicate function can be used to write arbitrary filters. The function is called for each element of array. The final result is an array of those elements that the predicate returned true for.

    谓词函数可以用来编写任意的过滤器。对数组的每个元素调用该函数。最后的结果是谓词返回true的那些元素的数组。

    In your controller create a method to pick the items you want

    在您的控制器中创建一个方法来选择您想要的项目。

    $scope.isRightUndefined = function(item) {
      return item.isRight === undefined;
    }
    

    and change your repeat to be

    把你的重复变成

    <li ng-repeat="link in nav | filter:isRightUndefined">
    

    #4


    4  

    module.filter('notNullOrUndefined', [function () {
        return function (items, property) {
            var arrayToReturn = [];
            for (var i = 0; i < items.length; i++) {
                var test = property !== undefined ? items[i][property] : items[i];
                if (test !== undefined && test !== null) {
                    arrayToReturn.push(items[i]);
                }
            }
            return arrayToReturn;
        };
    }]);
    

    Usage:

    用法:

    <div class="col-md-12" ng-repeat="style in styles | notNullOrUndefined:'background'">
        <span class="ed-item">{{style.name}} Background</span>
    </div>