Как использовать ng-if с ng-repeat?
У меня есть простая настройка объекта навигации, в которой перечислены элементы nav (и должны ли они отображаться в основном навигаторе или нет). Кажется, что когда я пытаюсь смешать ng-if с ng-repeat, все разваливается, но когда я смешиваю ng-show с ng-repeat, он отлично работает (но в итоге я получаю кучу скрытых элементов, хотите добавить в DOM).
<section class="nav">
<a ng-repeat="(key, item) in route.routes"
ng-href="{{key}}"
ng-show="item.nav"
>
{{item.label}}
</a>
</section>
Но следующее не работает (обратите внимание, что ng-show
теперь ng-if
):
<section class="nav">
<a ng-repeat="(key, item) in route.routes"
ng-href="{{key}}"
ng-if="item.nav"
>
{{item.label}}
</a>
</section>
Объект маршрутов выглядит как
routes: {
'/home': { label: 'Home', nav: true },
'/contact': { label: 'Contact', nav: false},
// etc
}
При попытке использовать ng-if
я получаю следующую ошибку:
Ошибка: несколько директив [ngIf, ngRepeat] с просьбой о включении:
Я предполагаю, что это пытается сказать мне, что я не могу заявить это выражение для существующего дважды. Я мог бы использовать ng-if
для внутреннего элемента, но я думаю, что все равно получаю кучу пустых внешних тегов a
.
Ответы
Ответ 1
Вероятно, лучшее решение, но после прочтения ответов выше вы можете попробовать создать свой собственный фильтр:
angular.module('yourModule').filter('filterNavItems', function() {
return function(input) {
var inputArray = [];
for(var item in input) {
inputArray.push(input[item]);
}
return inputArray.filter(function(v) { return v.nav; });
};
});
Затем, чтобы использовать его:
<section class="nav">
<a ng-repeat="(key, item) in routes | filterNavItems"
ng-href="{{key}}">
{{item.label}}
</a>
</section>
Здесь Plunker: http://plnkr.co/edit/srMbxK?p=preview
Ответ 2
Вместо ng-if
вам следует использовать фильтр http://docs.angularjs.org/api/ng.filter:filter), чтобы исключить определенные элементы из вашего списка.
Ответ 3
Я столкнулся с этой проблемой и нашел пару способов ее решения.
Первое, что я попробовал, - объединить ng-if
и ng-repeat
в пользовательскую директиву. Я скоро подниму это до github, но это kludgy.
Более простой способ сделать это - изменить коллекцию route.routes
(или создать коллекцию заполнителей)
$scope.filteredRoutes = {};
angular.forEach($scope.route.routes, function(item, key) {
if (item.nav) { $scope.filteredRoutes[key] = item; }
};
и на ваш взгляд
...
<a ng-repeat="(key, item) in filteredRoutes"
...
Если вам нужно, чтобы он динамически обновлялся, просто установите часы и т.д.
Ответ 4
Вы должны использовать фильтр в ng-repeat
вместо использования ng-if
.
Это должно работать:
<section class="nav">
<a ng-repeat="(key, item) in route.routes | filter:item.nav"
ng-href="{{key}}">
{{item.label}}
</a>
</section>
Предупреждение: я действительно не протестировал этот код.
Ответ 5
Как об этом однострочном лайнере с использованием $filter:
$scope.filteredRoutes = $filter('filter')($scope.route.routes, function(route){
return route.nav;
});