本文翻译自:When to favor ng-if vs. ng-show/ng-hide?
I understand that ng-show
and ng-hide
affect the class set on an element and that ng-if
controls whether an element is rendered as part of the DOM. 我知道ng-show
和ng-hide
会影响元素上设置的类,并且ng-if
控制元素是否呈现为DOM的一部分。
Are there guidelines on choosing ng-if
over ng-show
/ ng-hide
or vice-versa? 是否有关于选择ng-if
不是ng-show
/ ng-hide
或相反的指南?
#1楼
参考:https://stackoom.com/question/1TlCN/什么时候支持ng-if和ng-show-ng-hide
#2楼
Depends on your use case but to summarise the difference: 取决于您的用例,但总结出不同之处:
-
ng-if
will remove elements from DOM.ng-if
将从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, whenng-if
evaluates to false, that element will be removed from DOM and your click handler will not work any more, even afterng-if
later evaluates to true and displays the element. 例如,如果将单击处理程序绑定到子元素之一,则当ng-if
评估为false时,该元素将从DOM中删除,并且即使ng-if
之后评估为true且该点击处理程序也将不再起作用。显示元素。 You will need to reattach the handler. 您将需要重新连接处理程序。 -
ng-show/ng-hide
does not remove the elements from DOM.ng-show/ng-hide
不会从DOM中删除元素。 It uses CSS styles to hide/show elements (note: you might need to add your own classes). 它使用CSS样式隐藏/显示元素(注意:您可能需要添加自己的类)。 This way your handlers that were attached to children will not be lost. 这样,您与孩子结伴的处理程序不会丢失。 -
ng-if
creates a child scope whileng-show/ng-hide
does notng-if
创建子范围,而ng-show/ng-hide
不创建子范围
Elements that are not in the DOM have less performance impact and your web app might appear to be faster when using ng-if
compared to ng-show/ng-hide
. 不在DOM中的元素对性能的影响较小,与ng-show/ng-hide
相比,使用ng-if
时,您的Web应用程序似乎更快。 In my experience, the difference is negligible. 以我的经验,差异可以忽略不计。 Animations are possible when using both ng-show/ng-hide
and ng-if
, with examples for both in the Angular documentation. 当同时使用ng-show/ng-hide
和ng-if
,可以使用动画,并在Angular文档中都提供了示例。
Ultimately, the question you need to answer is whether you can remove element from DOM or not? 最终,您需要回答的问题是是否可以从DOM中删除元素?
#3楼
See here for a CodePen that demonstrates the difference in how ng-if/ng-show work, DOM-wise. 请参见此处的CodePen,它演示了ng-if / ng-show在DOM方面的工作方式的差异。
@markovuksanovic has answered the question well. @markovuksanovic已经很好地回答了这个问题。 But I'd come at it from another perspective: I'd always use ng-if
and get those elements out of DOM, unless: 但是我会从另一个角度进行探讨:我将始终使用ng-if
并将这些元素从DOM中删除,除非:
- you for some reason need the data-bindings and
$watch
-es on your elements to remain active while they're invisible. 由于某种原因,您需要元素上的数据绑定和$watch
-es在不可见时保持活动状态。 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. 也就是说 ,如果您发现自己手动附加和分离处理程序,以致在使用ng-if时丢失了重要状态,请问一下自己是否可以在数据模型中更好地表示该状态,并且处理程序在任何时候都可以通过指令有条件地应用元素被渲染。 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. 从DOM中获取数据,并将其放入模型中。 The presence/absence of the handlers should be determined by the data, and thus easy to recreate. 处理程序的存在与否应由数据确定,因此易于重新创建。
Angular is written really well. Angular的编写非常好。 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. 但是它的作用是使困难的事情(如2路数据绑定)看起来很容易的一大堆魔术。 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. 您可能会惊奇地发现,在$digest
循环中,对于一个甚至没人都在看的DOM块,setter函数被评估了数百或数千次。 And then you realize you've got dozens or hundreds of invisible elements all doing the same thing... 然后您意识到自己有数十或数百个不可见元素都在做同一件事...
Desktops may indeed be powerful enough to render most JS execution-speed issues moot. 桌面的确可能强大到足以解决大多数JS执行速度问题。 But if you're developing for mobile, using ng-if whenever humanly possible should be a no-brainer. 但是,如果您是为移动设备开发的,那么只要有可能,使用ng-if就可以了。 JS speed still matters on mobile processors. JS速度在移动处理器上仍然很重要。 Using ng-if is a very easy way to get potentially-significant optimization at very, very low cost. 使用ng-if是一种非常简单的方法,可以以非常非常低的成本获得潜在的重大优化。
#4楼
如果ng-include和ng-controller上的ng-if会对ng-include产生重大影响,除非ng-controller上的flag为true,否则它将不会加载所需的partial并且不会进行处理,除非flag为true是,但问题是当ng-中的标志变为false时,如果在标志变为true时它将从DOM中删除,则在这种情况下ng-show会更好,但一次显示ng-if会重新加载DOM
#5楼
One important note: 重要说明:
ngIf (unlike ngShow) usually creates child scopes that may produce unexpected results. ngIf(与ngShow不同)通常创建子范围,可能会产生意外结果。
I had an issue related to this and I've spent MUCH time to figure out what was going on. 我有一个与此相关的问题,我花了很多时间弄清楚发生了什么。
(My directive was writing its model values to the wrong scope.) (我的指令将其模型值写入错误的范围。)
So, to save your hair just use ngShow unless you run too slow. 因此,除非您运行太慢,否则请使用ngShow来保存头发。
The performance difference is barely noticable anyway and I am not sure yet on who's favour is it without a test... 无论如何,性能差异几乎没有引起注意,而且我不确定在没有测试的情况下谁会喜欢它。
#6楼
From my experience: 根据我的经验:
1) If your page has a toggle that uses ng-if/ng-show to show/hide something, ng-if causes more of a browser delay (slower). 1)如果您的页面具有使用ng-if / ng-show来显示/隐藏某些内容的切换,则ng-if会导致更多的浏览器延迟(较慢)。 For example: if you have a button used to toggle between two views, ng-show seems to be faster. 例如:如果您有一个用于在两个视图之间切换的按钮,则ng-show似乎更快。
2) ng-if will create/destroy scope when it evaluates to true/false. 2)ng-if在评估为true / false时将创建/销毁作用域。 If you have a controller attached to the ng-if, that controller code will get executed every time the ng-if evaluates to true. 如果您在ng-if上附加了控制器,则每次ng-if评估为true时,将执行该控制器代码。 If you are using ng-show, the controller code only gets executed once. 如果使用ng-show,则控制器代码仅执行一次。 So if you have a button that toggles between multiple views, using ng-if and ng-show would make a huge difference in how you write your controller code. 因此,如果您有一个在多个视图之间切换的按钮,那么使用ng-if和ng-show将在编写控制器代码方面产生巨大的差异。