如何从ng-repeat获得合并结果?

时间:2014-08-16 20:34:38

标签: javascript angularjs angularjs-directive angularjs-scope angularjs-ng-repeat

this plunker

<div ng-repeat="subCategory in subCategorys | filter:{tags:tag}:true | orderBy:'id'">
      {{subCategory.id}} {{subCategory.name}} {{subCategory.tags}}
      <br/><br/>
      You are now seeing details of <span ng-init="subCats = subCats + ' '  + subCategory.name">{{subCats}}</span>
    </div> 

此HTML页面显示来自对象的过滤结果。但是,我希望在“您现在看到详细信息”之后显示名称的合并结果,例如“您现在正在查看jim tom的详细信息”。该合并列表应出现在具有ng-repeat指令的元素之后。

如何做到这一点?

由于

3 个答案:

答案 0 :(得分:1)

您可以在HTML中执行此操作,方法是将整合列表移到ngRepeat之外并再次调用过滤器:

  <div ng-repeat="subCategory in subCategorys | filter:{tags:tag}:true | orderBy:'id'">
         {{subCategory.id}} {{subCategory.name}} {{subCategory.tags}}
         <br/><br/>
  </div>
  <div>
        You are now seeing details of 
        <span ng-repeat="subCategory in subCategorys | filter:{tags:tag}:true | orderBy:'id'">
                  {{subCategory.name}}&nbsp;
        </span>
  </div>

这种方法的缺点是你要调用过滤器两次。更好的选择是在父控制器中设置$ watch并手动调用$ filter。即将过滤后的结果保存在范围变量中。好处是过滤器被调用的次数减少了一半,并且您设置的范围变量对原始列表和合并列表可见。

app.controller('ParentController', function($scope, $filter) {
        $scope.subCategorys = [{...}];
        $scope.tag = {...};
        $scope.$watchCollection('subCategorys', function(newList){
               //if the collection changes, create a new tag 
               //reference that is a copy of the old one to trigger 
               //the tag watch listener
               if (newList)
                   $scope.tag = angular.copy($scope.tag);
        });
        $scope.$watch('tag', function(newTag){
               // if tag changes, apply the filter, 
               // and save the result to a scope variable
               if(newTag)
                    $scope.filteredList = $filter('filter')
                          ($scope.subCategories, { tags: newTag},  true);
        });

});

HTML

<div ng-controller="ParentController">

  <div ng-repeat="subCategory in filteredList | orderBy:'id'">
         {{subCategory.id}} {{subCategory.name}} {{subCategory.tags}}
         <br/><br/>
  </div>
  <div>
        You are now seeing details of 
        <span ng-repeat="subCategory in filteredList | orderBy:'id'">
                  {{subCategory.name}}&nbsp;
        </span>
  </div>

</div>

答案 1 :(得分:1)

我为你做了updated plunker

请尝试让您的示例更加简洁,以便将来更好地解决具体问题,因为这有助于我们为您提供帮助。

首先,我将搜索绑定添加为ng-repeat的过滤器,以使过滤器可用:

<div ng-repeat="subCategory in subCategorys | filter:{tags:tag}:true | filter:{id:search} | orderBy:'id'">

为避免执行过滤器两次,您可以通过简单地将过滤结果直接保存到范围变量中(在我的示例中为subCategorysFilter):

<div ng-repeat="subCategory in subCategorysFilter = (subCategorys | filter:{tags:tag}:true | filter:{id:search} | orderBy:'id')">

我进一步改变了你的getAllFilteredNames()方法,将过滤器对象作为参数,并使其遍历结果,构建一个名称数组,并以,作为分隔连接它们:

  $scope.getAllFilteredNames = function(filter){
    var names = [];
    angular.forEach(filter, function(element){
      names.push(element.name);
    });
    return names.join(", ");
  };

现在在ng-repeat指令之外调用它:

You are now seeing details of {{getAllFilteredNames(subCategorysFilter)}}

玩得开心!


更新

获得多线输出的两种可能解决方案:

1 - 您可以更改行

<div>You are now seeing details of {{getAllFilteredNames(subCategorysFilter)}}</div>

<div>You are now seeing details of <span ng-bind-html="getAllFilteredNames(subCategorysFilter)"></span></div>

然后表达式中的任何html标记都被编译为html代码。但默认情况下,角度禁用此功能有一些重要原因。如果您的对象可由用户编辑,则需要通过转义所有html标记来防止它们破坏您的设计......

2 - 但如果您不需要在单个字符串中显示合并信息,您可以简单地使用另一个ng-repeat与<ul>结合使用:

<div>You are now seeing details of <br/>
  <ul>
    <li ng-repeat="subCategory in subCategorysFilter">{{subCategoryName}}</li>
  </ul>
</div>

只需相应地设置li的样式,以便彼此显示,然后您就可以了。

答案 2 :(得分:0)

我担心除了选择subCategory之外没办法做到这一点。幸运的是,有一个非常优雅的角度&#39;这样做的方式。将其添加到您的控制器:

$scope.getSubCatById = function(someId) {
  return $filter('filter')($scope.subCategorys, {id:someId})[0]; 
}

然后是你的HTML:

<div ng-repeat="subCategory in subCategorys | filter:{tags:tag}:true | orderBy:'id'">
      {{subCategory.id}} {{subCategory.name}} {{subCategory.tags}}
      <br/><br/>
      You are now seeing details of {{ getSubCatById(2).name }}
</div> 

我希望我正确地解释你的问题。