【问题标题】:Angular items loading twice, but only sometimesAngular 项目加载两次,但只是有时
【发布时间】:2016-10-02 14:18:25
【问题描述】:

所以我正在做一个项目,在该项目中我使用 Angular 基于模板加载一些下拉面板(在项目中称为“构面”),并且仅在某些浏览器/硬件组合上,它会加载构面两次并删除第二对.这是一个视频,说明了正在发生的事情:

https://drive.google.com/open?id=0BywtASGJVCWmYXpSbE1zV3QxanM

(对格式感到抱歉)。有趣的是,这仅发生在视频中的 Chrome 安装上(也就是说,我已经用安装在不同计算机上的相同 Chrome 版本对其进行了测试,并且它没有重现错误)以及 IE 11 和 Edge都安装在我自己的电脑上。我在构造函数中添加了一个console.log("made a multiselect facet"),用于某种类型的方面(显然是多选),并检查了它被打印了多少次。左边是 Edge 输出,右边是 Firefox 开发者版:

因此您可以看到,在页面加载期间,构面被创建了两次,但只在 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 包含在 facet 的实际模板中:http://pastebin.com/VcQHGp8L 及其控制器:@987654325 @

一些注意事项:控制器都是打字稿,而不是 javascript。此外,这与 angular.js github 上的问题 #6006 相关,因为除非我非常错误地这是从 angular 的 1.5.6 版开始修复的,这是我拥有的.任何其他信息均可应要求提供。

提前致谢!

【问题讨论】:

  • 不确定这是否是您的问题的原因,但您的 html 确实有 1 个问题对我来说很突出。只有有限的一组 html 元素支持自关闭标签 (/&gt;),您无法添加更多。在不受支持的元素(即任何指令)上使用自闭合标签可能会导致下一个同级元素被完全忽略或渲染不正确。
  • 另外......我们应该在那个视频中看到什么?对我来说没有什么比这更奇怪了……
  • 如果您在侧边栏面板上查看大约 00:12,您会注意到它们的副本被添加到下方并被迅速删除。在第一个页面加载中,您什么都看不到,但我已通过 console.log() 确认正在发生相同的错误,只是速度太快了。
  • 另外,RE 自动关闭标签,我改变了它们(见编辑),但它没有解决任何问题。并不是我真的期望它,这只是一个很好的改变,谢谢。
  • 最好在ng-repeat 语句中使用子句track by $index。添加后可以检查吗?检查stackoverflow.com/questions/27754386/…,因为您也在使用orderBy

标签: javascript html angularjs typescript


【解决方案1】:

始终使用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 阻止了它们。

您可以为每个ng-repeat 使用track by $index,这不仅可以防止重复,还可以提高性能。再次参考文档,

如果您正在处理具有标识符属性的对象,则应按标识符而不是整个对象进行跟踪。如果您稍后重新加载数据,ngRepeat 将不必为它已经呈现的项目重建 DOM 元素,即使集合中的 JavaScript 对象已被替换为新对象。对于大型集合,这显着提高了渲染性能。如果您没有唯一标识符,按 $index 进行跟踪也可以提高性能。

希望这能回答你的问题。

【讨论】:

  • 对我的更新的更新:实际上,这确实适用于任何地方,我只是在一个页面上处理一个边缘情况,其中只有一个多方面要加载。看,问题在于,Firefox 正在从一个脚本调用中折叠多个相同的语句,并附加一个数字,显示消息重复了多少次,我直到现在才注意到,而 Edge 只显示了它们。所以是的,这完全回答了我的问题,谢谢。
猜你喜欢
  • 1970-01-01
  • 2022-10-24
  • 2022-11-07
  • 1970-01-01
  • 1970-01-01
  • 2012-12-05
  • 2019-08-03
  • 1970-01-01
  • 2021-09-09
相关资源
最近更新 更多