【问题标题】:orderBy in inner loop on nested ng-repeat嵌套 ng-repeat 的内部循环中的 orderBy
【发布时间】:2015-02-15 13:51:44
【问题描述】:

我要过滤掉属于过滤类别的网站,并按排名顺序显示。代码sn-p为:

<div ng-repeat="category in categories | filter:{will return more than one category}">
    <div ng-repeat="website in websites | orderBy:'rank'| filter:{ parent_id : category.id }:true">
      {{website.title}},{{website.rank}}
   </div>
</div>

但是在嵌套循环中,由于orderby在内部循环中,它对外部循环的每次迭代都有效,但整体结果不按等级排序。假设有三个类别,过滤器给出 cat1 &cat2。如果排名为 6,2,5 的网站是 cat1 和 cat2 中的 9,1,那么结果将是 2,5,6,1,9。我希望结果是 1,2,5,6,9。如何我应该这样做吗?

我应该在某个函数中传递类别并编写 js 代码以获取过滤后的网站数组,然后对其进行排序并将它们返回给模板,还是在模板本身中有其他更好的方法来做到这一点?

【问题讨论】:

  • 您似乎只想删除类别并按排名排序。我会在控制器中创建该数组并使用一次重复。
  • 我想过滤属于按类别过滤器过滤的类别组的网站。如果只有一个类别,orderBy 会起作用,但对于多个类别,它会给出我所说的结果有问题
  • 没错,所以我的意思是 - 在您的控制器中 - 获取带有类别的数据,循环/foreach 并创建您想要显示的对象数组。

标签: javascript angularjs nested-loops


【解决方案1】:

我认为你想做的事,不能照原样做。无论如何,您可以使用custom filter

新答案

此方法为您提供了一个类别选择机制,作为您如何使用此自定义过滤器的另一个示例。

angular.module('app',[])

// categories
.value('categories',  [ { id: 0, title:"first" }, { id: 1, title:"second" }, { id: 2, title:"third" } ])

// websites
.value('websites',  [   { rank: 3, parent_id: 2, title: "Alice" },
                        { rank: 1, parent_id: 1, title: "Bob" },
                        { rank: 9, parent_id: 1, title: "Carol" },
                        { rank: 2, parent_id: 0, title: "David" },
                        { rank: 4, parent_id: 0, title: "Emma" },
                        { rank: 5, parent_id: 0, title: "Foo" } ])

// controller, 
.controller('ctrl', ['$scope', 'categories', 'websites', function($scope, categories, websites) {
    // categories injected
    $scope.categories = categories;
    // websites injected
    $scope.websites = websites;  
    // categories selection helper, useful for preselection
    $scope.selection = { 0: true, 1:false }  // 2: false (implicit)
  
}])

                     
// categories filter, categories injected.
.filter('bycat', ['categories', function(categories) {

  // websites is the result of orderBy :'rank', selection helper passed as paramenter.
  return function(websites, selection) {
    
    // just an Array.prototype.filter
    return websites.filter(function(website) {
          // for each category                    
          for(var i=0; i < categories.length; i++) {
              var cat = categories[i];
              // if category is selected and website belongs to category
              if (selection[cat.id] && cat.id == website.parent_id) { 
                  // include this website
                  return true;
              } 
          }
          // exclude this website
          return false;
     });
  };
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" ng-controller="ctrl">
  <span ng-repeat="category in categories">
      <label class="checkbox" for="{{category.id}}">
        <input type="checkbox" ng-model="selection[category.id]" name="group" id="{{category.id}}" />
        {{category.title}}
      </label>
    </span>
  <div ng-repeat="website in websites | orderBy:'rank'| bycat: selection">
    <p>Rank:{{website.rank}} - {{website.title}} ({{categories[website.parent_id].title}})</p>
  </div>
</div>

老答案

Se 代码 cmets。

angular.module('app',[])

// categories will be injected in custom filter.
.value('categories',  [ { id: 1, title:"first" }, { id: 2, title:"second" } ])

.controller('ctrl', function($scope) {        
    // sample websites
    $scope.websites = [ { rank: 1, parent_id: 2, title: "Site w/rank 1" },
                        { rank: 9, parent_id: 2, title: "Site w/rank 9" },
                        { rank: 2, parent_id: 1, title: "Site w/rank 2" },
                        { rank: 4, parent_id: 1, title: "Site w/rank 4" },
                        { rank: 5, parent_id: 1, title: "Site w/rank 5" } ];
  
})

// custom filter, categories injected.
.filter('bycat', ['categories', function(categories) {

  // websites is the result of orderBy :'rank'
  return function(websites, catText) {    
    
    // just an Array.prototype.filter
    return websites.filter(function(website) {
          // if no filter, show all.
          if (!catText) return true;
         
          for(var i=0; i < categories.length; i++) {
              var cat = categories[i];
              // if matches cat.title and id == parent_id, gotcha!
              if (cat.title.indexOf(catText) != -1 && cat.id == website.parent_id) { 
                  return true;
              } 
          }
          // else were 
          return false;
      });
  };
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" ng-controller="ctrl">
  <input type="text" ng-model="filterText">
  <p>Try "first" and "second"</p>
  <div ng-repeat="website in websites | orderBy:'rank'| bycat: filterText ">
    {{website.title}},{{website.rank}}
  </div>
</div>

【讨论】:

    猜你喜欢
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 2015-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多