我知道ng-show和ng-hide会影响元素上的类集,而ng-if控制元素是否作为DOM的一部分呈现。

是否有关于选择ng-if而不是ng-show/ng-hide或反之的指导方针?


这取决于你的用例,但总结一下区别:

ng-if will remove elements from DOM. This means that all your handlers or anything else attached to those elements will be lost. For example, if you bound a click handler to one of child elements, when ng-if evaluates to false, that element will be removed from DOM and your click handler will not work any more, even after ng-if later evaluates to true and displays the element. You will need to reattach the handler. ng-show/ng-hide does not remove the elements from DOM. It uses CSS styles to hide/show elements (note: you might need to add your own classes). This way your handlers that were attached to children will not be lost. ng-if creates a child scope while ng-show/ng-hide does not

不在DOM中的元素对性能的影响较小,使用ng-if比ng-show/ng-hide更快。根据我的经验,这种差异可以忽略不计。当同时使用ng-show/ng-hide和ng-if时,动画是可能的,Angular文档中有这两者的示例。

最终,您需要回答的问题是是否可以从DOM中删除元素?


请参阅这里的CodePen,它演示了ng-if/ng-show在dom方面如何工作的差异。

@markovuksanovic很好地回答了这个问题。但我从另一个角度来看待它:我总是使用ng-if并从DOM中获取这些元素,除非:

you for some reason need the data-bindings and $watch-es on your elements to remain active while they're invisible. Forms might be a good case for this, if you want to be able to check validity on inputs that aren't currently visible, in order to determine whether the whole form is valid. You're using some really elaborate stateful logic with conditional event handlers, as mentioned above. That said, if you find yourself manually attaching and detaching handlers, such that you're losing important state when you use ng-if, ask yourself whether that state would be better represented in a data model, and the handlers applied conditionally by directives whenever the element is rendered. Put another way, the presence/absence of handlers is a form of state data. Get that data out of the DOM, and into a model. The presence/absence of the handlers should be determined by the data, and thus easy to recreate.

Angular is written really well. It's fast, considering what it does. But what it does is a whole bunch of magic that makes hard things (like 2-way data-binding) look trivially easy. Making all those things look easy entails some performance overhead. You might be shocked to realize how many hundreds or thousands of times a setter function gets evaluated during the $digest cycle on a hunk of DOM that nobody's even looking at. And then you realize you've got dozens or hundreds of invisible elements all doing the same thing...

台式机可能确实强大到足以让大多数JS执行速度问题变得毫无意义。但如果你开发的是移动平台,那么尽可能使用ng-if应该是一件很简单的事情。JS的速度在移动处理器上仍然很重要。使用ng-if是一种非常简单的方法,可以以非常非常低的成本获得潜在的重要优化。


如果对ng-include和对ng-controller都有很大影响的事情 在ng-include上,它将不加载所需的部分,除非flag为true,否则不进行处理 在ng-controller上,除非flag为true,否则它不会加载控制器 但问题是,当ng-if中的标志为false时,它将从DOM中删除,当flag为true时,它将重新加载DOM,在这种情况下ng-show更好,一次show ng-if更好


重要提示:

ngIf(不像ngShow)通常会创建可能产生意外结果的子作用域。

我有一个与此相关的问题,我花了很多时间来弄清楚发生了什么。

(我的指令是把它的模型值写入错误的范围。)

所以,为了保存你的头发,只要使用ngShow,除非你运行得太慢。

无论如何,性能差异几乎不明显,没有测试我还不确定谁更喜欢……


根据我的经验:

1)如果你的页面使用ng-if/ng-show来显示/隐藏某些内容,ng-if会导致更多的浏览器延迟(更慢)。例如:如果您有一个按钮用于在两个视图之间切换,ng-show似乎更快。

2) ng-if在评估为true/false时创建/销毁作用域。如果你有一个附加到ng-if的控制器,那么每当ng-if计算为true时,该控制器代码就会被执行。如果使用ng-show,控制器代码只执行一次。因此,如果你有一个按钮可以在多个视图之间切换,使用ng-if和ng-show会使你编写控制器代码的方式有很大的不同。


如果您使用ng-show或ng-hide内容(例如。来自服务器的缩略图)将被加载,而不管表达式的值,但将根据表达式的值显示。

如果使用ng-if,只有当ng-if表达式的计算结果为真值时,才会加载内容。

如果您要从服务器加载数据或图像,并仅根据用户交互显示这些数据或图像,那么使用ng-if是一个好主意。这样你的页面加载就不会被不必要的密集任务阻塞。


答案并不简单:

这取决于目标机器(手机还是台式机),取决于数据的性质、浏览器、操作系统、运行的硬件……如果您真的想知道,就需要进行基准测试。

这主要是内存和计算的问题…与大多数性能问题一样,对于重复的元素(n),如列表,尤其是嵌套的(n x n,或更糟),以及在这些元素中运行什么样的计算,差异会变得很大:

ng-show: If those optional elements are often present (dense), like say 90% of the time, it may be faster to have them ready and only show/hide them, especially if their content is cheap (just plain text, nothing to compute or load). This consumes memory as it fills the DOM with hidden elements, but just show/hide something which already exists is likely to be a cheap operation for the browser. ng-if: If on the contrary elements are likely not to be shown (sparse) just build them and destroy them in real time, especially if their content is expensive to get (computations/sorted/filtered, images, generated images). This is ideal for rare or 'on-demand' elements, it saves memory in terms of not filling the DOM but can cost a lot of computation (creating/destroying elements) and bandwidth (getting remote content). It also depends on how much you compute in the view (filtering/sorting) vs what you already have in the model (pre-sorted/pre-filtered data).