AngularJS - 如果子循环为空(隐藏),则隐藏父元素

时间:2013-07-15 10:59:57

标签: angularjs

我有一个案例,其中我有嵌套循环,其中子类由一个以父作为参数的过滤函数构造。我还有另一个只进行文本比较的过滤器。这是示例

<div ng-repeat="group in groups">
  {{group.name}}
  <div ng-repeat="material in materials | filter:filterByGroup(group) | filter:search ">
    {{material.name}}
  </div>
</div>

现在,我的问题是,当应用filter:search并过滤掉特定组中的所有结果时,我想要隐藏该组(并且不要将空group.name挂起而不使用子元素)。

我自己的组中没有这些材料,所以我在父ng-repeat范围内没有这些信息。问题是,是否有一种方法可以访问嵌套的ng-repeat并从父级查看其计数,如果该计数为0,则隐藏父级。

更新

这是一个更好地解释情况的小提琴:fiddle

主要问题是我不想将我的资料与群体联系起来。我可以这样做,如果没有其他工作,但它听起来像一个重载(因为我需要基本上过滤结果两次),如果我可以通过只检查嵌套循环。

由于

3 个答案:

答案 0 :(得分:26)

建议使用更清晰的解决方案HERE

您需要做的是使用ng-show / ng-if基于在数据结构上应用过滤器并提取长度的表达式来包装相关区域。以下是它在您的示例中的工作原理:

  <div ng-show="(materials | filter:filterByGroup(group)).length">
    <div ng-repeat="group in groups">
      {{group.name}}
      <div ng-repeat="material in materials | filter:filterByGroup(group) | filter:search ">
        {{material.name}}
      </div>
    </div>
  </div>

这允许您在复杂结构由于过滤而变空时隐藏它们,例如结果表。

答案 1 :(得分:8)

我已经看过几次这个用例,这是我的解决方案:

<div ng-repeat="group in groups">
    <div ng-repeat="material in materials | filter:filterByGroup(group) | filter:search ">
        <span ng-show="$first">
            {{group.name}}<br/>
        </span>
        {{material.name}}
    </div>
</div>

您可以在ng-repeat的范围内使用$ first或$ last来仅显示每个组的第一个和最后一个。如果没有$ first,则不会显示组名。

我刚刚在blog上实现了此功能,并在此更新了您的小提琴:http://jsfiddle.net/ke793/1/

我不确定这是否是最优雅的解决方案,但它看起来相当简单且有效。我很想知道其他人是如何解决这个问题的。

更新:刚刚意识到您可以使用ng-if来防止群组名称在$first元素之外的任何地方点击dom。比ng-hide / ng-show更清晰,每次都会将display: none设置为额外的标题。

答案 2 :(得分:1)

如果您可以按组询问材料,并且您希望为每个组执行此操作,那么为什么不在初始化视图并使用具有材料的组构建模型时立即执行此操作?如果可以这样做,您可以使用ng-show仅隐藏具有材料的组。

你似乎需要知道一个团体是否有材料?这是一个小提琴,不知道很多背景故事:

<div ng-controller="MyCtrl">

  <div ng-repeat="group in groups">
      <div ng-show="groupHasMaterials(group)">{{group.name}}</div>
      <div ng-repeat="material in materialsByGroup(group)">
          <div>{{material.name}}</div>
      </div>
  </div>

</div>


<script>
var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {

    var groups = [
        {'name':'group one'},
        {'name':'group two'}
    ];

    var materials = [
        {'name':'material1'},
        {'name':'material2'},
        {'name':'material3'}
    ];

    $scope.groups = groups;
    $scope.materials = materials;

    $scope.groupHasMaterials = function(group){
        return $scope.materialsByGroup(group).length > 0;    
    }

    $scope.materialsByGroup = function(group){
        return group.name === 'group one' 
            ? [materials[0], materials[1]] 
            : [];
    }
}
</script>

fiddle with groups