15

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

<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 时隐藏父级。

更新

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

主要问题是我不想将我的材料与组相关联。如果没有其他方法,我可以这样做,但如果我可以通过检查嵌套循环来做到这一点,这听起来像是一个重载(因为我基本上需要过滤两次结果)。

谢谢

4

3 回答 3

26

这里建议了一个更清洁的解决方案。

您需要做的是使用 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>

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

于 2013-09-17T14:28:27.790 回答
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,则不会显示组名。

我刚刚在我的博客上实现了这个并在这里更新了你的小提琴:http: //jsfiddle.net/ke793/1/

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

更新:刚刚意识到您可以使用它来防止组名在元素ng-if之外击中 dom 。$first比 ng-hide/ng-show 稍微干净一点,它display: none每次都设置为额外的标题。

于 2013-09-07T23:37:41.507 回答
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>

摆弄团体

于 2013-07-15T12:31:35.390 回答