如果在ng-repeat内,检查值是否在ng-array中

时间:2015-05-05 17:07:13

标签: javascript angularjs

我有一个ng-repeat循环遍历从API中检索到的葡萄酒列表。我还有一个数组变量,其中包含已添加到从数据库中获取的收藏夹中的所有wine ID。如果用户尚未从列表中添加特定结果wine,我希望能够显示“添加到收藏夹”按钮。要做到这一点,我想我会做类似的事情:

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()的新手,所以我想也许这就是问题所在。但也许我错了。

5 个答案:

答案 0 :(得分:28)

您可以使用angular-filter's contains filter

<span ng-if="favorites | contains:wine.Id">Added</span>

或编写自己的过滤器,并执行相同的操作:

angular.module('module').filter('contains', function() {
  return function (array, needle) {
    return array.indexOf(needle) >= 0;
  };
});

答案 1 :(得分:12)

我建议你将这个逻辑移到控制器上,让你的视图尽可能干净:

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

答案 2 :(得分:5)

我认为你必须改变

favorites.indexOf(wine.Id) !> -1

favorites.indexOf(wine.Id) < 0

答案 3 :(得分:1)

favorites.indexOf(wine.Id) !> -1看起来不像是一个合适的角度表达。请注意,当您在模板中使用表达式时,只允许使用一些基本的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

使用UnderscoreLodash可以更优雅地完成此类数组操作。

请注意,如果您有一个带有葡萄酒的对象(ID为关键),则可以通过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>

答案 4 :(得分:0)

&GT!;无效。 !只能与=一起使用,或者使用布尔值。使用

favorites.indexOf(wine.Id) == -1

如果indexOf无法在数组中找到该元素,则返回-1。 谢谢你的纠正。我被困住了!&gt;