【问题标题】:AngularJS - filter for undefined properties in ng-repeat?AngularJS - 在 ng-repeat 中过滤未定义的属性?
【发布时间】:2014-01-30 22:46:55
【问题描述】:

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

在一个ng-repeat 中,我想用未定义的isRight 属性过滤那些对象。如何在 ng-repeat 属性中完成此操作,而不必求助于创建自定义过滤器函数?

$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}">

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

【问题讨论】:

  • 遇到了同样的问题。我使用prop: undefined 过滤属性没有值的情况,使用prop: {} 过滤属性是对象的情况。问题是,当财产丢失时,这些都不包括在内。感谢您提出这个问题,它帮助我找到了!!! 的魔力!

标签: javascript angularjs


【解决方案1】:

您可以否定过滤器表达式。因此,您可以过滤掉isRight 不是(!)为真的任何内容,而不是处理undefined。像这样:

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

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

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

demo fiddle

【讨论】:

  • 谢谢!我多次尝试过类似的事情,但是除了 inside 引号之外,到处都是否定。一个简单的ng-if 是我之前完成它的唯一方法。
  • edit:即便如此,我还是希望有一些更优雅的东西,它给人的印象是属性可能是未定义的,而不仅仅是!truefalse
  • 是的,可能值得在此处发表评论,明确表示 !true 案例意味着捕获未定义 isRight 的导航元素。
【解决方案2】:

你也可以使用 &lt;li ng-repeat="link in nav | filter:{isRight:'!'}"&gt;

另见How to display placeholders in AngularJS for undefined expression values?

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>

【讨论】:

  • 哦,是的,这才是真正的宝贝
  • 不错的一个!需要过滤掉没有 id 属性的对象,并且执行以下操作就像一种享受:ng-repeat="entry in entries | filter: { id: '!!' }
  • 这是我要找的答案,应该排名更高!
  • 松散类型语言的好妈妈
【解决方案3】:

编辑

我只是重读了这个问题,这不是您要寻找的答案。我将把它留在这里用于文档目的,但我认为没有一种方法可以在不构建自定义过滤器或使用自定义过滤器函数的情况下获得您想要的功能。

为了解释为什么寻找 undefined 不适用于默认过滤器,我们看一下来自 AngularJS filter 实现的 this 代码。

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

如果过滤器对象的属性值为undefined,则不会向谓词数组添加谓词函数。在您的情况下,您将isRight 属性的值设置为undefined(您的过滤器表达式为{isRight:undefined})。

原答案

您始终可以使用谓词函数来创建任意过滤器 (documentation)。

谓词函数可用于编写任意过滤器。这 为数组的每个元素调用函数。最终结果是一个 谓词返回 true 的那些元素的数组。

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

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

并将重复更改为

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

【讨论】:

  • 这是一个很好的答案,但是是的,这不是我所希望的。我也相信为其他人可能偶然发现的文档留下答案,甚至在一个被接受后留下答案。目前,我正在使用@KayakDave 的解决方案。
  • 您的原始答案实际上似乎在 Angular 1.2.1 中对我有用:jsfiddle.net/Cg8kF/90
【解决方案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;
    };
}]);

用法:

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

【讨论】:

  • 感谢您的代码 - 下次我需要这样的东西时它会很有用。然而,我最初的问题是如何在不求助于自定义过滤器的情况下完成这样的事情。
猜你喜欢
  • 2014-09-30
  • 2014-06-21
  • 1970-01-01
  • 1970-01-01
  • 2015-02-24
  • 2013-05-09
  • 2020-06-18
  • 2015-04-28
  • 2018-05-13
相关资源
最近更新 更多