AngularJs - ngRepeat与返回一个新的对象的过滤器 [英] AngularJs - ngRepeat with a filter that returns a new object

查看:109
本文介绍了AngularJs - ngRepeat与返回一个新的对象的过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在我的过滤器,这会导致新的对象的数组返回给应用转换的对象。这是因为欲之后应用转换来过滤的对象,并显示转换的结果。不过,我结束了无限的消化,因为我显示的对象是比我放在对象不同(比较它们的当$$ IDS )。我的想法来解决这个如下:

I'm trying to apply a transformation to the objects in my filter, which results in an array of new objects being returned. This is because I want to filter the objects AFTER the transformation is applied and display the results of the transformation. However, I end up with an infinite digest because the objects I display are different than the objects I put in (when comparing their $$ids). My thoughts to solve this are the following:


  1. 由item.id 使用跟踪前pression像追踪和分配原来的对象 IDS 每个变换对象。虽然我的所有对象目前确实有一个 ID ,这似乎是一个好主意,因为它使过滤器更常规 - 原来的对象必须有一个 ID ,改造不能设置 ID (因为它会被覆盖)等。

  1. Use a tracking expression like track by item.id and assign the original objects' ids to each of the transformed objects. While all my objects currently do have an id, this seems like a bad idea because it makes the filter much less general- the original objects must have an id, the transformation must not set an id (as it will be overwritten), etc.

指定原始对象的 $$ ID 来变换对象。这似乎hackish的,根据我的理解 $$ ID 应该是只读的。

Assign the original object's $$id to the transformed objects. This seems hackish, based on my understanding $$id is supposed to be read only.

返回的基础上改造的滤波的结果的原始对象的子集。这可能会导致性能问题的转变需要在过滤器和显示器前pression都适用,而且我必须回送通过转换/过滤项目选择正确的原有的回归。

Return a subset of the original objects based on the result of the transformation's filtering. This may cause performance issues as the transformation needs to be applied in both the filter and the display expression, AND I have to loop back through the transformed / filtered items to select the right original ones to return.

下面是过滤器:

listModule.filter('ui.filter.transformFilter',
                 ['$filter',
                  '$id',
                   function($filter, $id)
  {
    var Filter = $filter('filter');
    return function(objects, transformer, expression) {
      // precondition- we need a list of objects
      if (!_.isArray(objects)) {
        return objects;
      }

      var transformed = [];
      for (var i = 0; i < objects.length; i++) {
        transformed[i] = transformer(objects[i]);
      }

      return filtered = Filter(transformed, expression);
    }                  
  }]
);

和这里是如何我试图使用它:

And here is how I am trying to use it:

  <tr ng-repeat="item in list.items | ui.filter.transformFilter:list.transformerFunction:list.search" ng-click="list.select({'item': item})" class="list-item">
    <td ng-repeat="label in list.labels" ng-bind-html="item[label.key]"></td>
  </tr>

哦,最好 ngClick 返回原始的对象,但我总能环绕它的功能看这件事。

Oh, and ideally ngClick returns the original object, but I can always wrap a function around it to look that up.

推荐答案

一个解决这个问题,你有一个幂函数,即角,由于对象ID,认为不幂等(从而导致$消化循环问题,因为你提到)是使用LO-破折号/下划线的 _。memoize的 缓存你的函数的结果

One solution to this problem where you have an idempotent function that Angular, due to object IDs, thinks is not idempotent (and thus causes the $digest loop issue as you noted) is to use lo-dash/underscore's _.memoize to cache your function's results.

这将保证任何给定的缓存键过滤器总是会返回一个完全一致的对象(包括 $$ ID )。这样,您就不必玩游戏$$ ID 和你不必重新计算筛选结果在每个性能优势$消化循环。

This will guarantee that for any given cache key your filter will always return a completely identical object (including $$id). This way you don't have to play games with $$id and you get the performance benefit of not having to recompute the filter results on each $digest loop.

下面是你如何可以缓存过滤器的结果:

Here's how you could cache your filter's results:

return _.memoize(function(objects, transformer, expression) { ... },
                 function(objects,transformer,expression){ 
                    return objects +transformer.name + expression;
                  });   

您的具体情况的一个重要的一点是,默认情况下 _。memoize的使用第一个函数参数(对象中这种情况下),为高速缓存密钥。由于您的过滤器可能会产生给予不同变压器的功能和前pressions不同的结果我已经添加了可选的第二个参数 - 使用对象的哈希函数前pression 变压器的名称函数产生一个缓存键。

One important note for your situation is that by default _.memoize uses the first function parameter (objects in this case) as the cache key. Since your filter likely produces different results given different transformer functions and expressions I've added the optional second parameter- a hash function that uses objects,expression, and the name of the transformer function to produce a cache key.

下面是使用code的简化版本:小提琴

Here's a simplified version of your code using this: fiddle

这篇关于AngularJs - ngRepeat与返回一个新的对象的过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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