Подтвердить что ты не робот

AngularJS - фильтр для свойств undefined в ng-repeat?

В моем проекте AngularJS (v1.2.3) у меня есть список маршрутов, и я пытаюсь создать панель навигации с объекта. Я хочу показать любой объект с свойством undefined isRight в одном стиле и где свойство определено в другом.

В одном ng-repeat я хотел бы отфильтровать эти объекты с помощью свойства undefined 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}">

Это скорее любопытство, чем необходимость, но я ценю любые предложения.

4b9b3361

Ответ 1

Вы можете скрыть выражение фильтра. Поэтому вместо того, чтобы иметь дело с undefined, вы можете просто отфильтровать все, где isRight не (!) true. Вот так:

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

И, наоборот, вы можете, конечно, сделать:

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

демонстрационная скрипка

Ответ 2

Вы также можете использовать <li ng-repeat="link in nav | filter:{isRight:'!'}">

см. также Как отображать заполнители в выражениях AngularJS для undefined?

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

Edit

Я просто перечитал вопрос, и это не тот ответ, который вы ищете. Я оставлю его здесь для целей документации, но я не думаю, что есть способ получить желаемую функциональность, не создавая настраиваемый фильтр или не используя специальную функцию фильтра.

Чтобы узнать, почему поиск undefined не будет работать с фильтром по умолчанию, мы рассмотрим этот код из 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;
  ...
}

Если значение для свойства объекта фильтра равно undefined, предикатная функция не добавляется в массив предикатов. В вашем случае вы устанавливаете значение свойства isRight на undefined (ваше выражение фильтра {isRight:undefined}).

Оригинальный ответ

Вы всегда можете использовать функцию предиката для создания произвольных фильтров (documentation).

Функция предиката может использоваться для записи произвольных фильтров. функция вызывается для каждого элемента массива. Конечным результатом является массив из тех элементов, которые предикат возвратил true для.

В вашем контроллере создайте метод для выбора нужных элементов

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

и измените ваше повторение на

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

Ответ 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>