Проверьте, находится ли значение в массиве для ng-if внутри ng-repeat
У меня есть цикл ng-repeat, проходящий через список вин, полученных из API. У меня также есть переменная массива, содержащая все идентификаторы вин, которые были добавлены в избранное из базы данных. Я хочу иметь возможность отображать кнопку "Добавить в избранное", если пользователь еще не добавил в список конкретное вино результата. Чтобы сделать это, я подумал, что сделаю что-то вроде:
HTML:
<tr ng-repeat="wine in wines">
<td>{{$index+1}}</td>
<td>{{ wine.Name }}</td>
<td>{{ wine.Appellation.Name }}</td>
<td>${{ wine.PriceMin }} - ${{ wine.PriceMax }}</td>
<td>
<!-- If wine.Id is not yet in the array of all favorite ids, display "Add Button" -->
<a href="#" class="btn btn-primary btn-dark" ng-click="addToFavorites(wine.Id)" ng-if="favorites.indexOf(wine.Id) !> -1"> Add </a>
<!-- Else Display Already Added -->
<span ng-if="favorites.indexOf(wine.Id) > -1">Added</span>
</td>
</tr>
Вот мой JS:
app.controller("MainController", function($scope, $http){
$scope.favorites = [];
var getAllFavorites = function(){
$http.get("/home/getAllFavoriteIds").success(function(response) {
angular.forEach(response, function(r) {
$scope.favorites.push(r);
});
});
};
});
Я новичок в .indexOf(), поэтому я думаю, что это проблема. Но, возможно, я ошибаюсь.
Ответы
Ответ 1
Вы можете использовать angular -фильтр содержит фильтр:
<span ng-if="favorites | contains:wine.Id">Added</span>
или напишите свой собственный фильтр, который делает то же самое:
angular.module('module').filter('contains', function() {
return function (array, needle) {
return array.indexOf(needle) >= 0;
};
});
Ответ 2
Я бы рекомендовал вам переместить эту логику на контроллер, чтобы ваше представление было максимально чистым:
$scope.isFavorites = function(id) {
return $scope.favorites.indexOf(id) !== -1;
}
И ваше мнение должно быть:
<!-- If wine.Id is not yet in the array of all favorite ids, display "Add Button" -->
<a href="#" class="btn btn-primary btn-dark" ng-click="addToFavorites(wine.Id)" ng-if="!isFavorites(wine.Id)">Add</a>
<!-- Else Display Already Added -->
<span ng-if="isFavorites(wine.Id)>Added</span>
Ответ 3
Думаю, вам нужно изменить
favorites.indexOf(wine.Id) !> -1
в
favorites.indexOf(wine.Id) < 0
Ответ 4
favorites.indexOf(wine.Id) !> -1
не выглядит как правильное выражение angular. Обратите внимание, что при наличии выражений в ваших шаблонах допускаются только некоторые базовые условия javascript. См. docs для возможного.
Вместо того, чтобы иметь список всех вин и список с любимыми винами, лучше расширить список со всеми винами с булевым свойством isFavorite
. Это также лучше для производительности, так как не нужно искать вино во втором списке на каждой итерации.
В цикле обратного вызова ответа (быстрый и грязный):
var index = $scope.favorites.indexOf(r.id);
if(index > -1) {
$scope.favorites[index].isFavorite = true;
} // else isFavorite is undefined, which is falsy
Операции массива, подобные этому, можно сделать более элегантно с помощью Underscore или Lodash.
Обратите внимание, что если у вас есть объект с винами (ids как ключ), вина могут быть восстановлены по id вместо поиска по индексу каждый раз. ngRepeat
поддерживает объекты, подобные массивам.
В вашем шаблоне:
<!-- If wine.Id is not yet in the array of all favorite ids, display "Add Button" -->
<a href="#" class="btn btn-primary btn-dark" ng-click="addToFavorites(wine.Id)" ng-if="!wine.isFavorite"> Add </a>
<!-- Else Display Already Added -->
<span ng-if="wine.isFavorite">Added</span>
Ответ 5
! > недействителен.! может использоваться только с = или с булевым значением. Используйте
favorites.indexOf(wine.Id) == -1
indexOf возвращает -1, если он не может найти элемент в массиве.
Спасибо за исправление. Я застрял! >