棱角分明的分组过滤器 [英] angular grouping filter

查看:110
本文介绍了棱角分明的分组过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

随着<一个href=\"http://stackoverflow.com/questions/14123307/angular-js-conditional-markup-in-ng-repeat\">angular.js在NG-重复条件的标记,我试着创作,它集合了自定义过滤器。我打的问题有关对象的身份与被看更改模型,但想到我终于钉它,因为在控制台弹出了没有错误。

Following angular.js conditional markup in ng-repeat, I tried to author a custom filter that does grouping. I hit problems regarding object identity and the model being watched for changes, but thought I finally nailed it, as no errors popped in the console anymore.

原来我错了,因为现在当我尝试将其与其他过滤器结合起来(用于分页),像这样

Turns out I was wrong, because now when I try to combine it with other filters (for pagination) like so

<div ng-repeat="r in blueprints | orderBy:sortPty | startFrom:currentPage*pageSize | limitTo:pageSize | group:3">
      <div ng-repeat="b in r">

我得到了可怕的10 $摘要()达到迭代。中止!再次出现错误信息。

I get the dreaded "10 $digest() iterations reached. Aborting!" error message again.

下面是我的组过滤器:

filter('group', function() {
  return function(input, size) {
    if (input.grouped === true) {
      return input;
    }
  var result=[];
  var temp = [];
  for (var i = 0 ; i < input.length ; i++) {
      temp.push(input[i]);
      if (i % size === 2) {
          result.push(temp);
          temp = [];
      }
  }
  if (temp.length > 0) {
      result.push(temp);
  }
  angular.copy(result, input);
  input.grouped = true;
  return input;
}; 
}).

请注意两者使用 angular.copy ,并在输入 .grouped 标记,但没有效果: (
我知道的的例如的<一个href=\"http://stackoverflow.com/questions/13277542/10-digest-iterations-reached-aborting-due-to-filter-using-angularjs\">"10 $摘要()迭代到达。 !中止&QUOT;由于使用angularjs 但很明显,我过滤器没有得到它。

Note both the use of angular.copy and the .grouped marker on input, but to no avail :( I am aware of e.g. "10 $digest() iterations reached. Aborting!" due to filter using angularjs but obviously I did not get it.

此外,我想分组逻辑是有点幼稚,但那是另一回事。任何帮助将大大AP preciated,因为这是推动我疯了。

Moreover, I guess the grouping logic is a bit naive, but that's another story. Any help would be greatly appreciated, as this is driving me crazy.

推荐答案

它看起来像真正的问题在这里你改变你的输入,而不是创建一个新的变量,并允许输出,从您的过滤器。这将触发任何东西的手表是看变量你输入。

It looks like the real problem here is you're altering your input, rather than creating a new variable and outputing that from your filter. This will trigger watches on anything that is watching the variable you've input.

有真的没有理由中增加了分组==真检查在那里,因为你应该对自己的过滤器的完全控制。但是,如果这是你的应用程序是必须的,那么你要添加分组== true以你的过滤器,而不是输入的结果。

There's really no reason to add a "grouped == true" check in there, because you should have total control over your own filters. But if that's a must for your application, then you'd want to add "grouped == true" to the result of your filter, not the input.

的方式过滤器的工作是他们改变输入,然后返回不同的东西,然后用previous过滤器的下一个过滤器的交易结果......所以你的过滤检查将主要irrelavant 项目在项目|过滤器1 |过滤器2 |过滤器3 ,其中过滤器1过滤项,过滤器2过滤过滤器1的结果,而过滤器3过滤过滤器2的结果......如果是有道理的。

The way filters work is they alter the input and return something different, then the next filter deals with the previous filters result... so your "filtered" check would be mostly irrelavant item in items | filter1 | filter2 | filter3 where filter1 filters items, filter2 filters the result of filter1, and filter3 filters the result of filter 2... if that makes sense.

下面是我刚刚刮起。我不知道(但)如果它的工作原理,但它给你的基本理念。你会带一侧的数组,你吐出另一数组的数组。

Here is something I just whipped up. I'm not sure (yet) if it works, but it gives you the basic idea. You'd take an array on one side, and you spit out an array of arrays on the other.

app.filter('group', function(){
   return function(items, groupSize) {
      var groups = [],
         inner;
      for(var i = 0; i < items.length; i++) {
         if(i % groupSize === 0) {
            inner = [];
            groups.push(inner);
         }
         inner.push(items[i]);
      }
      return groups;
   };
});

HTML

<ul ng-repeat="grouping in items | group:3">
    <li ng-repeat="item in grouping">{{item}}</li>
</ul>


修改

也许是更好地看到你的code所有这些过滤器,但它看起来像它导致问题,因为它不断地需要在$摘要进行重新评估。所以,我建议你做这样的事情:

Perhaps it's nicer to see all of those filters in your code, but it looks like it's causing issues because it constantly needs to be re-evaluated on $digest. So I propose you do something like this:

app.controller('MyCtrl', function($scope, $filter) {
   $scope.blueprints = [ /* your data */ ];
   $scope.currentPage = 0;
   $scope.pageSize = 30;
   $scope.groupSize = 3;
   $scope.sortPty = 'stuff';

   //load our filters
   var orderBy = $filter('orderBy'),
       startFrom = $filter('startFrom'),
       limitTo = $filter('limitTo'),
       group = $filter('group'); //from the filter above

   //a method to apply the filters.
   function updateBlueprintDisplay(blueprints) {
        var result = orderBy(blueprints, $scope.sortPty);
        result = startForm(result, $scope.currentPage * $scope.pageSize);
        result = limitTo(result, $scope.pageSize);
        result = group(result, 3);
        $scope.blueprintDisplay = result;
   }

   //apply them to the initial value.
   updateBlueprintDisplay();

   //watch for changes.
   $scope.$watch('blueprints', updateBlueprintDisplay);
});

然后在您的标记:

then in your markup:

<ul ng-repeat="grouping in blueprintDisplay">
   <li ng-repeat="item in grouping">{{item}}</li>
</ul>

...我敢肯定,里面还有错别字,但是这是基本的想法。

... I'm sure there are typos in there, but that's the basic idea.

再次编辑:我知道你已经接受了这个答案,但是要做到这一点笔者近日了解到另一种方式,你可能更喜欢:

EDIT AGAIN: I know you've already accepted this answer, but there is one more way to do this I learned recently that you might like better:

<div ng-repeat="item in groupedItems = (items | group:3 | filter1 | filter2)">
    <div ng-repeat="subitem in items.subitems">
    {{subitem}}
    </div>
</div>

这将在你的$范围内创建一个新的属性名为$ scope.groupedItems对飞,这应该有效地缓存你的过滤,分组结果。

This will create a new property on your $scope called $scope.groupedItems on the fly, which should effectively cache your filtered and grouped results.

试一试,让我知道,如果它的工作原理为你。如果没有,我猜对方的回答可能会更好。

Give it a whirl and let me know if it works out for you. If not, I guess the other answer might be better.

这篇关于棱角分明的分组过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆