AngularJS – 在ng-repeat中过滤未定义的属性?

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

在一个ng-repeat我想用一个未定义的isRight属性过滤这些对象。 我怎么能在ng-repeat属性里面完成这个,而不必求助于创build一个自定义的filter函数呢?

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

我意识到我可以将属性isRight: false添加到每个对象,或者有单独的导航对象的右侧和左侧链接,以及其他这样的简单解决方法,但我很好奇,如果有一种方法来完成与当前结构,使用以下方面的东西:

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

这是一个比需求更好奇,但我感谢任何build议。

您可以否定filterexpression式。 因此,不要处理undefined ,只要过滤掉isRight不是( ! )true的任何东西。 喜欢这个:

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

而相反,你可以这样做:

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

演示小提琴

您也可以<li ng-repeat="link in nav | filter:{isRight:'!'}">使用<li ng-repeat="link in nav | filter:{isRight:'!'}">

另请参阅如何在AngularJS中显示未定义expression式值的占位符?

 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> 

编辑

我只是重读这个问题,这不是你正在寻找的答案。 我将把它留在这里作为文档的目的,但我不认为有一种方法来获得你想要的function,而不build立一个自定义的filter或使用自定义filterfunction。

为了扩展为什么寻找undefined将不能使用默认的filter,我们来看看AngularJS filter实现中的这个代码。

 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; ... } 

如果undefinedfilter对象属性的值,则谓词数组中不会添加谓词函数。 在你的情况下,你正在设置isRight属性的值为undefined (你的filterexpression式是{isRight:undefined} )。

原始答复

您始终可以使用谓词函数来创build任意filter( 文档 )。

一个谓词函数可以用来写任意的filter。 该函数为数组的每个元素调用。 最终结果是谓词返回true的那些元素的数组。

在你的控制器中创build一个方法来select你想要的项目

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

并改变你的重复

 <li ng-repeat="link in nav | filter:isRightUndefined"> 
 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; }; }]); 

用法:

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