【发布时间】:2017-09-26 08:50:06
【问题描述】:
显然我还不了解ng-repeat、$$hashKeys 和track by 背后的机制。
我目前在我的项目中使用 AngularJS 1.6。
问题:
我得到了一个复杂对象的数组,我想用它们在我的视图中呈现一个列表。但要获得所需的结果,我需要先修改(或映射/增强/更改)这些对象:
const sourceArray = [{id: 1, name: 'Dave'}, {id:2, name: Steve}]
const persons = sourceArray.map((e) => ({enhancedName: e.name + e.id}))
//Thus the content of persons is:
//[{enhancedName: 'Dave_1'}, {enhancedName: 'Steve_2'}]
将它绑定到视图应该像这样工作:
<div ng-repeat="person in ctrl.getPersons()">
{{person.enhancedName}}
</div>
但这显然会遇到$digest()-循环,因为.map 每次调用时都会返回新的对象实例。由于我通过一个函数将它绑定到 ng-repeat,它会在每个 $digest 中重新评估,模型不稳定并且 Angular 不断重新运行 $digest-cycles,因为这些对象被标记为 $dirty。
我为什么感到困惑
现在这不是一个新问题,有几种解决方案:
在an Angular-Issue from 2012Igor Minar 自己建议手动设置 $$hashKey-Property 来告诉 angular 生成的对象是相同的。 This 是他的工作小提琴,但由于即使是这个非常微不足道的例子在我的项目中使用它时仍然遇到$digest-loop,我尝试在小提琴中升级 Angular-Version。出于某种原因it crashes。
好的...从 Angular 1.3 开始,我们有了track by,它应该基本上解决了这个确切的问题。然而两者都
<div ng-repeat="person in ctrl.getPersons() track by $index">
和
<div ng-repeat="person in ctrl.getPersons() track by person.enhancedName">
$digest-loop 导致崩溃。我的印象是track by 语句应该让 Angular 相信它适用于相同的对象,但显然情况并非如此,因为它只是不断检查它们是否有变化。老实说,我不知道如何正确调试导致此问题的原因。
问题:
是否可以使用过滤/修改的数组作为 ng-repeat 的数据源?
我不想将修改后的数组存储在我的控制器上,因为我需要不断更新其数据,然后必须在控制器中手动维护和刷新它,而不是依赖数据绑定。
【问题讨论】:
-
一个(现在已删除)答案询问有关实际用例的更多详细信息:我的应用程序中的
sourceArray比此示例中的复杂得多。因此,我想从中删除视图不需要的所有数据(为了便于阅读)。除此之外,我需要将一些信息和业务逻辑映射到其他数据类型(即“当这个数组有 10 个或更多条目时,这个切换按钮应该呈现为‘点击’”)要正确地将它与 ng-model 绑定,我会喜欢将Object.defineProperty与包含相应业务逻辑的自定义 getter 和 setter 方法一起使用。
标签: javascript angularjs angularjs-ng-repeat