AngularJs - ngRepeat与返回一个新的对象的过滤器 [英] AngularJs - ngRepeat with a filter that returns a new object
问题描述
我试图在我的过滤器,这会导致新的对象的数组返回给应用转换的对象。这是因为欲之后应用转换来过滤的对象,并显示转换的结果。不过,我结束了无限的消化,因为我显示的对象是比我放在对象不同(比较它们的当$$ 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:
-
由item.id 使用跟踪前pression像
追踪和分配原来的对象
IDS
每个变换对象。虽然我的所有对象目前确实有一个ID
,这似乎是一个好主意,因为它使过滤器更常规 - 原来的对象必须有一个ID
,改造不能设置ID
(因为它会被覆盖)等。
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 anid
, this seems like a bad idea because it makes the filter much less general- the original objects must have anid
, the transformation must not set anid
(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屋!