【发布时间】:2014-03-19 02:55:51
【问题描述】:
我了解ng-show 和ng-hide 会影响元素上设置的类,而ng-if 控制是否将元素呈现为DOM 的一部分。
是否有关于选择 ng-if 而不是 ng-show/ng-hide 或反之亦然的指南?
【问题讨论】:
-
与dart 语言无关。
标签: angularjs angularjs-directive
我了解ng-show 和ng-hide 会影响元素上设置的类,而ng-if 控制是否将元素呈现为DOM 的一部分。
是否有关于选择 ng-if 而不是 ng-show/ng-hide 或反之亦然的指南?
【问题讨论】:
标签: angularjs angularjs-directive
取决于您的用例,但总结一下区别:
ng-if 将从 DOM 中删除元素。这意味着您的所有处理程序或附加到这些元素的任何其他内容都将丢失。例如,如果您将点击处理程序绑定到子元素之一,当 ng-if 评估为 false 时,该元素将从 DOM 中删除,并且您的点击处理程序将不再工作,即使在 ng-if 稍后评估为 true 并且显示元素。您需要重新附加处理程序。ng-show/ng-hide 不会从 DOM 中删除元素。它使用 CSS 样式来隐藏/显示元素(注意:您可能需要添加自己的类)。这样,您的附加到孩子的处理程序就不会丢失。ng-if 创建子作用域,而 ng-show/ng-hide 没有与ng-show/ng-hide 相比,使用ng-if 时,不在DOM 中的元素对性能的影响较小,并且您的Web 应用程序可能看起来更快。根据我的经验,差异可以忽略不计。当同时使用ng-show/ng-hide 和ng-if 时,动画是可能的,Angular 文档中都有这两个示例。
最终,您需要回答的问题是您是否可以从 DOM 中删除元素?
【讨论】:
ng-if 一起使用。检查动画段落和docs 中的示例。同样对于ng-hide/ng-show,:first-child 或:nth-child 等css 选择器将无法正常工作,因为隐藏的元素也会被计算在内。
ng-if 会创建一个新范围,而 ng-show 不会。
请参阅 here 了解 CodePen,它演示了 ng-if/ng-show 工作方式的差异,DOM 方式。
@markovuksanovic 很好地回答了这个问题。但我会从另一个角度来看:我总是使用ng-if 并将这些元素从 DOM 中取出,除非:
$watch-es 在它们不可见时保持活动状态。如果您希望能够检查当前不可见的输入的有效性,以确定整个表单是否有效,那么表单可能是一个很好的例子。Angular 写得非常好。考虑到它的作用,它很快。但它所做的是一大堆魔法,让困难的事情(比如 2 路数据绑定)看起来非常简单。让所有这些事情看起来很容易需要一些性能开销。您可能会惊讶地发现,在$digest 循环中,一个 setter 函数被评估了数百次或数千次,而这块 DOM 甚至没有人在看。然后你意识到你有几十个或几百个不可见的元素都在做同样的事情......
桌面可能确实足够强大,可以解决大多数 JS 执行速度问题。但是,如果您正在为移动设备开发,那么在人为可能的情况下使用 ng-if 应该是不费吹灰之力的。 JS 速度在移动处理器上仍然很重要。使用 ng-if 是一种非常简单的方法,可以以非常非常低的成本获得潜在的显着优化。
【讨论】:
ng-show 在你有的时候很有用,比如每个标签都有很多需要时间渲染的内容。在第一次渲染之后,选项卡之间的移动将是即时的,而ng-if 需要重新渲染、绑定事件等。正如你所说的,缺点是创建在后台执行的手表。 Angular 迫切需要ng-ifshowwatch
ng-if on ng-include 和 on ng-controller 会有很大的影响 在 ng-include 上,它不会加载所需的部分,并且除非标志为真,否则不会处理 在 ng-controller 上,除非标志为真,否则它不会加载控制器 但问题是当一个标志在 ng 中为假时,如果它会从 DOM 中删除,当标志恢复为真时,它将重新加载 DOM,在这种情况下,ng-show 更好,一次显示 ng-if 更好
【讨论】:
一个重要提示:
ngIf(与 ngShow 不同)通常会创建可能产生意外结果的子作用域。
我遇到了一个与此相关的问题,我花了很多时间来弄清楚发生了什么。
(我的指令将其模型值写入错误的范围。)
所以,为了节省你的头发,除非你跑得太慢,否则只需使用 ngShow。
无论如何,性能差异几乎不明显,我还不确定谁会在没有测试的情况下受到青睐......
【讨论】:
$parent.scopevar 将纠正使用 ngIf 时出现的子范围问题
ngIf 放在任何地方,他们相信这会提高性能。这根本不是真的,如果没有在特定情况下进行测试或深入分析,就不能说哪个最好,ngIf 或ngShow。所以,我仍然建议忘记ngIf,直到看到表现不佳或知道自己在做什么
根据我的经验:
1) 如果您的页面有一个使用 ng-if/ng-show 来显示/隐藏某些内容的切换,那么 ng-if 会导致更多的浏览器延迟(更慢)。例如:如果你有一个用于在两个视图之间切换的按钮,ng-show 似乎更快。
2) ng-if 将在评估为真/假时创建/销毁作用域。如果您有一个控制器附加到 ng-if,则每次 ng-if 评估为 true 时都会执行该控制器代码。如果您使用 ng-show,控制器代码只会执行一次。因此,如果您有一个可以在多个视图之间切换的按钮,那么使用 ng-if 和 ng-show 将对您编写控制器代码的方式产生巨大的影响。
【讨论】:
如果您使用ng-show or ng-hide,则无论表达式的值如何,内容(例如来自服务器的缩略图)都将被加载,但将根据表达式的值显示。
如果您使用ng-if,则仅当 ng-if 的表达式计算结果为真时才会加载内容。
在您要从服务器加载数据或图像并仅根据用户交互显示这些数据或图像的情况下,使用 ng-if 是一个好主意。这样一来,您的页面加载就不会被不必要的 nw 密集型任务阻塞。
【讨论】:
img 标签的src 属性,当它出现时它会被加载!
答案并不简单:
这取决于目标机器(移动设备还是桌面设备),取决于数据的性质、浏览器、操作系统、运行它的硬件……如果您真的想知道,您需要进行基准测试。
这主要是内存与计算的问题...与大多数性能问题一样,对于列表之类的重复元素 (n),差异可能会变得显着,尤其是在嵌套时(nxn,或更糟)以及您在其中运行什么样的计算这些元素:
ng-show:如果这些可选元素经常出现(密集),例如 90% 时间,让它们准备好并且只显示/隐藏它们可能会更快,特别是如果它们的内容很便宜(只是纯文本,无需计算或加载)。这会消耗内存,因为它会用隐藏元素填充 DOM,但仅仅显示/隐藏已经存在的东西对浏览器来说可能是一种廉价的操作。
ng-if:相反,如果元素可能不会显示(稀疏),则只需实时构建并销毁它们,尤其是如果它们的内容获取成本很高(计算/排序/过滤,图像,生成的图像)。这对于稀有或“按需”元素来说是理想的,它在不填充 DOM 方面节省了内存,但可能会花费大量计算(创建/销毁元素)和带宽(获取远程内容)。它还取决于您在视图中的计算量(过滤/排序)与模型中已有的计算量(预排序/预过滤的数据)。
【讨论】: