如何使用ng-if与ng-repeat?

时间:2022-11-25 15:51:11

I have a simple nav object setup that lists the nav items (and whether they should appear in the primary nav or not). It seems though when I try to mix ng-if with ng-repeat, things fall apart, but when I mix ng-show with ng-repeat it works fine (but I end up with a bunch of hidden elements that I don't want appended to the DOM).

我有一个简单的nav对象设置,列出nav项目(以及它们是否应该出现在主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>

But the following doesn't work (note the ng-show is now ng-if):

但是下面的方法不起作用(注意,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>

The routes object looks like

路由对象看起来是这样的。

routes: {
    '/home': { label: 'Home', nav: true },
    '/contact': { label: 'Contact', nav: false},
   // etc
}

I receive the following error when trying to use ng-if:

我在尝试使用ng-if时收到如下错误:

Error: Multiple directives [ngIf, ngRepeat] asking for transclusion on:

错误:多个指令[ngIf, ngRepeat]要求屏蔽:

I guess it's trying to tell me that I can't state it's declaration for existing twice. I could use ng-if on an inner element, but I think I would still end up with a bunch of empty outer a tags.

我猜它是想告诉我,我不能声明它是存在两次的声明。我可以在内部元素上使用ng-if,但是我认为我最终还是会得到一堆空的外部标签。

5 个解决方案

#1


18  

There's probably a better solution, but after reading the replies above, you can try making your own custom filter:

可能有更好的解决方案,但是在阅读了上面的回复之后,您可以尝试自己做一个自定义过滤器:

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; });
  };
});

Then to use it:

然后使用它:

<section class="nav">
    <a  ng-repeat="(key, item) in routes | filterNavItems"
        ng-href="{{key}}">
            {{item.label}}
    </a>
</section>

Here's the Plunker: http://plnkr.co/edit/srMbxK?p=preview

这是砰砰作响:http://plnkr.co/edit/srMbxK?p=preview

#2


5  

Instead of ng-if you should use a filter (http://docs.angularjs.org/api/ng.filter:filter) on you ng-repeat to exclude certain items from your list.

如果你应该使用一个过滤器(http://docs.angularjs.org/api/ng.filter:filter:filter),而不是ng,那么你就可以从列表中排除某些条目。

#3


2  

I ran into this problem as well, and found a couple ways to solve it.

我也遇到了这个问题,并找到了一些解决方法。

The first thing I tried was to combine ng-if and ng-repeat into a custom directive. I'll push that up to github sometime soon, but it's kludgy.

我尝试的第一件事是将ng-if和ng-repeat合并到一个自定义指令中。我很快就会把它推到github上,但它很笨拙。

The simpler way to do it is to modify your route.routes collection (or create a placeholder collection)

更简单的方法是修改你的路线。路由集合(或创建占位符集合)

$scope.filteredRoutes = {};
angular.forEach($scope.route.routes, function(item, key) {
    if (item.nav) { $scope.filteredRoutes[key] = item; }
};

and in your view

在你看来

...
<a  ng-repeat="(key, item) in filteredRoutes"
...

If you need it to be dynamically updated, just set up watches, etc.

如果需要动态更新,只需设置手表等。

#4


1  

How about this one-liner using $filter:

这个使用$filter的一行程序怎么样:

$scope.filteredRoutes = $filter('filter')($scope.route.routes, function(route){
  return route.nav;
});

#5


0  

You should use a filter in your ng-repeat instead of using ng-if.

您应该在ng-repeat中使用一个过滤器,而不是使用ng-if。

This should work:

这应该工作:

<section class="nav">
    <a  ng-repeat="(key, item) in route.routes | filter:item.nav"
        ng-href="{{key}}">
            {{item.label}}
    </a>
</section>

Warning: I haven't actually tested this code.

警告:我还没有实际测试过这个代码。

#1


18  

There's probably a better solution, but after reading the replies above, you can try making your own custom filter:

可能有更好的解决方案,但是在阅读了上面的回复之后,您可以尝试自己做一个自定义过滤器:

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; });
  };
});

Then to use it:

然后使用它:

<section class="nav">
    <a  ng-repeat="(key, item) in routes | filterNavItems"
        ng-href="{{key}}">
            {{item.label}}
    </a>
</section>

Here's the Plunker: http://plnkr.co/edit/srMbxK?p=preview

这是砰砰作响:http://plnkr.co/edit/srMbxK?p=preview

#2


5  

Instead of ng-if you should use a filter (http://docs.angularjs.org/api/ng.filter:filter) on you ng-repeat to exclude certain items from your list.

如果你应该使用一个过滤器(http://docs.angularjs.org/api/ng.filter:filter:filter),而不是ng,那么你就可以从列表中排除某些条目。

#3


2  

I ran into this problem as well, and found a couple ways to solve it.

我也遇到了这个问题,并找到了一些解决方法。

The first thing I tried was to combine ng-if and ng-repeat into a custom directive. I'll push that up to github sometime soon, but it's kludgy.

我尝试的第一件事是将ng-if和ng-repeat合并到一个自定义指令中。我很快就会把它推到github上,但它很笨拙。

The simpler way to do it is to modify your route.routes collection (or create a placeholder collection)

更简单的方法是修改你的路线。路由集合(或创建占位符集合)

$scope.filteredRoutes = {};
angular.forEach($scope.route.routes, function(item, key) {
    if (item.nav) { $scope.filteredRoutes[key] = item; }
};

and in your view

在你看来

...
<a  ng-repeat="(key, item) in filteredRoutes"
...

If you need it to be dynamically updated, just set up watches, etc.

如果需要动态更新,只需设置手表等。

#4


1  

How about this one-liner using $filter:

这个使用$filter的一行程序怎么样:

$scope.filteredRoutes = $filter('filter')($scope.route.routes, function(route){
  return route.nav;
});

#5


0  

You should use a filter in your ng-repeat instead of using ng-if.

您应该在ng-repeat中使用一个过滤器,而不是使用ng-if。

This should work:

这应该工作:

<section class="nav">
    <a  ng-repeat="(key, item) in route.routes | filter:item.nav"
        ng-href="{{key}}">
            {{item.label}}
    </a>
</section>

Warning: I haven't actually tested this code.

警告:我还没有实际测试过这个代码。