因此,我正在一个项目中,使用angular使用基于模板的模板加载一些下拉面板(在项目中称为“ facets”),并且仅在某些浏览器/硬件组合上,它加载facets两次并删除第二对。这是一段视频,说明正在发生的事情:
https://drive.google.com/open?id=0BywtASGJVCWmYXpSbE1zV3QxanM
(对不起格式)。有趣的是,这仅发生在视频中的Chrome安装上(也就是说,我已经在另一台计算机上安装了相同的Chrome版本进行了测试,并且没有重现该错误),而IE 11和Edge安装在我自己的计算机上。我为构造类型的某个构面(显然是多重选择)添加了console.log("made a multiselect facet")
,并检查了它被打印了多少次。这是左边的Edge输出,右边是Firefox Developer Edition的图片:
因此,您可以看到在页面加载期间,构面创建了两次,但仅在Edge上创建(因为输出翻了一番)。我已经确认控制器脚本不会运行两次,只有“创建搜索条件”位,因此必须在元素实际添加到文档中时发生(我认为)。这是我在上面构面的页面的模板(无论如何相关部分):
<md-card ng-repeat="facet in directory.criteria.Facets track by $index">
<multi-Facet facet="facet"
clear-action="directory.clearFilter(facet)"
apply-action="directory.applyFilter(facet)"
ng-if="directory.isMultiselectFacet(facet)"></multi-Facet>
<ranged-Facet facet="facet"
clear-action="directory.clearFilter(facet)"
apply-action="directory.applyFilter(facet)"
ng-if="directory.isRangeFacet(facet)"></ranged-Facet>
</md-card>
因为它非常长,而且我不知道它是否有用,所以我将控制器作为pastebin:http://pastebin.com/xNQUfZqs包含在构面的实际模板中:http://pastebin.com/VcQHGp8L及其控制器:http://pastebin.com/PHfNEEn4
一些注意事项:控制器都是打字稿,不是javascript。另外,这与angular.js github上的问题#6006无关,因为除非我非常误解,否则从1.5.6版本的angular(我拥有的版本)开始就已将其修复。其他信息可应要求提供。
提前致谢!
最佳答案
始终将track by $index
短语与ng-repeat
一起使用,如下所示,
<md-card ng-repeat="facet in reqMan.criteria.Facets | orderBy:'DisplayOrder' track by $index">
为什么要防止重复?正如官方docs所说,
为了最大程度地减少DOM元素的创建,ngRepeat使用一个函数来“跟踪”集合中的所有项目及其对应的DOM元素。例如,如果将一个项目添加到集合中,则ngRepeat将知道所有其他项目已经具有DOM元素,并且不会重新呈现它们。
我不知道重复的原因是什么,但是
track by $index
阻止了它们。您可以对每个
track by $index
使用ng-repeat
,不仅可以防止重复,还可以提高性能。再次参考文档,如果要使用具有标识符属性的对象,则应按标识符而不是整个对象进行跟踪。如果您稍后重新加载数据,即使集合中的JavaScript对象已替换为新对象,ngRepeat也不必为其已呈现的项目重建DOM元素。对于大型集合,这可以显着提高渲染性能。如果没有唯一标识符,则按$ index跟踪也可以提高性能。
希望这能回答您的问题。
关于javascript - Angular 项目加载两次,但有时,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37598725/