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

AngularJS - Как структурировать настраиваемый фильтр с ng-repeat для возврата элементов условно

У меня есть ng-repeat, который печатает элементы списка. Я хочу написать настраиваемый фильтр, чтобы элемент списка печатался, только если условие истинно.

Кажется, что структура неправильная, поскольку переменные не передаются фильтру.

index.php

<div ng-show="userDetails.username" class="nav">
    <p>Menu</p>
    <li ng-repeat="menuItem in menu | matchAccessLevel:$rootScope.userDetails.accessLevel:menuItem.minAccess | orderBy:'position' ">
        <a ng-href="/angular-app/app/{{menuItem.id}}">{{menuItem.name}}</a>
    </li>
</div>

app.js

userApp.filter('matchAccessLevel', function() {
    return function( item, userAccessLevel, minAccessLevel ) {
        if( userAccessLevel >= minAccessLevel ) {
            return item;
        }
    }
});
4b9b3361

Ответ 1

Фильтры не работают с отдельными элементами в массиве, они преобразуют весь массив в другой массив.

userApp.filter('matchAccessLevel', function() {
  return function( items, userAccessLevel) {
    var filtered = [];
    angular.forEach(items, function(item) {
      if(userAccessLevel >= item.minAccess) {
        filtered.push(item);
      }
    });
    return filtered;
  };
});

Смотрите plnkr

** всегда проверяйте аргументы функции. Не всегда очевидно, что значения. *

см. руководство по фильтрам

Ответ 2

Вы можете использовать Array.filter для более сжатого решения:

app.filter('matchAccessLevel', function() {
    return function( items, userAccessLevel ) {
      return items.filter(function(element){
        return userAccessLevel >= element.minAccess;
      });
    }
});

Проверить Plunker

Ответ 3

Для любителей CoffeeScript:

userApp.filter 'matchAccessLevel', ->
  (items, userAccessLevel) ->
    item for item in items when userAccessLevel >= item.minAccess