什么时候使用ng-if和ng-show / ng-hide?
我明白, ng-show
和ng-hide
会影响在元素上设置的类, ng-if
控制元素是否作为DOM的一部分呈现。
是否有选择ng-if
在ng-show
/ ng-hide
上的指导原则,反之亦然?
取决于你的用例,但要总结一下:
-
ng-if
将从DOM中删除元素。 这意味着你所有的处理程序或任何与这些元素相关的东西都将丢失。 例如,如果你将一个点击处理程序绑定到一个子元素,那么当ng-if
值为false时,该元素将被从DOM中移除,并且你的点击处理程序将不再工作,即使在ng-if
之后ng-if
后来计算为true,显示元素。 您将需要重新附加处理程序。 -
ng-show/ng-hide
不会删除DOM中的元素。 它使用CSS样式来隐藏/显示元素(注意:您可能需要添加自己的类)。 这样一来,附属于孩子的处理程序就不会丢失。 -
ng-if
创建一个子范围,而ng-show/ng-hide
则不创建子范围
不在DOM中的元素具有较少的性能影响,并且在使用ng-if
与ng-show/ng-hide
相比时,您的web应用看起来可能会更快。 根据我的经验,差别可以忽略不计。 在Angular文档中同时使用ng-show / ng-hide和ng-if时,可以使用动画。
最终,您需要回答的问题是您是否可以从DOM中删除元素?
在这里看到一个CodePen,它演示了如何在ng-if / ng-show工作方面的差异。
@markovuksanovic已经很好地回答了这个问题。 但我从另一个角度来看它:我总是使用ng-if
并从DOM中获取这些元素,除非:
- 你出于某种原因需要你的元素上的数据绑定和
$watch
-es在它们不可见时保持活动状态。 如果您希望能够检查当前不可见的输入的有效性,以确定整个表单是否有效,则表单可能是一个很好的例子。 - 如上所述,您正在使用一些具有条件事件处理程序的非常复杂的有状态逻辑。 也就是说 ,如果您发现自己手动附加和分离处理程序,那么当您使用ng-if时,您将失去重要的状态,请问自己在数据模型中是否能更好地表示该状态,并且处理程序通过指令有条件地应用元素被渲染。 换句话说,处理程序的存在与否是一种状态数据。 从DOM中获取数据,并将其转换为模型。 处理程序的存在/不存在应由数据决定,因此易于重新创建。
Angular写得很好。 这很快,考虑到它的作用。 但是它所做的是一大堆魔法,它使得硬件(比如双向数据绑定)看起来非常简单。 使所有这些事情看起来很容易需要一些性能开销。 你可能会惊讶地发现,在一大堆DOM上的$digest
循环中,一个setter函数被评估了多少次或几千次,甚至没人看到。 然后你意识到你有几十个或数百个隐形元素都在做同样的事情…
桌面可能确实足够强大,可以解决大多数JS执行速度问题。 但是,如果你正在开发移动,使用ng-if只要人类可能应该是一个明智之举。 JS速度在移动处理器上仍然很重要。 使用ng-if是以非常低的成本获得潜在重要优化的一种非常简单的方法。
从我的经验:
1)如果你的页面有一个使用ng-if / ng-show来显示/隐藏某些内容的切换,那么ng-if导致更多的浏览器延迟(较慢)。 例如:如果你有一个按钮用来在两个视图之间切换,ng-show似乎更快。
2)ng-if在评估为真/假时会创建/销毁范围。 如果你有一个连接到ng-if的控制器,那么每当ng-if求值为真时,控制器代码就会被执行。 如果你使用ng-show,控制器代码只执行一次。 所以如果你有一个在多个视图间切换的按钮,那么使用ng-if和ng-show将会在编写你的控制器代码方面产生巨大的影响。
答案并不简单:
这取决于目标机器(移动设备和桌面设备),这取决于数据的性质,浏览器,操作系统以及运行的硬件……如果您真的想知道,则需要进行基准测试。
它主要是内存vs计算问题…与大多数性能问题一样,差异可以通过像列表这样的重复元素 (n)变得显着,特别是在嵌套 (nxn或更差)时,以及在这些元素内部运行什么类型的计算 :
-
ng-show :如果这些可选元素经常出现(密集),比如说90%的时间,准备好它们可能会更快,只显示/隐藏它们,特别是如果它们的内容很便宜(纯文本,计算或加载)。 这会消耗内存,因为它会用隐藏的元素填充DOM,但是只显示/隐藏已经存在的内容对于浏览器来说可能是一个便宜的操作。
-
ng-if :如果相反元素可能不会被显示(稀疏),那么只需构建它们并实时销毁它们,特别是如果它们的内容(计算/排序/过滤,图像,生成的图像)昂贵。 这对于罕见或“按需”元素来说是理想的,它可以节省内存,而不是填充DOM,但会花费大量计算(创建/销毁元素)和带宽(获取远程内容)。 这也取决于您在视图(过滤/排序)中计算的数量与模型中已有的数量(预先排序/预过滤的数据)。
一个重要的说明:
ngIf(与ngShow不同)通常会创建可能会产生意外结果的子范围。
我有一个相关的问题,我已经花了很多时间来弄清楚发生了什么事情。
(我的指令是将其模型值写入错误的范围。)
所以,要保存你的头发只要使用ngShow,除非你运行得太慢。
性能差异无论如何几乎是不明显的,我还不确定谁的青睐是没有测试…
如果你使用ng-show or ng-hide
,内容(例如服务器的缩略图)将被加载,而不管表达式的值如何,但是会根据表达式的值来显示。
如果使用ng-if
只有在ng-if的表达式评估为真的时才加载内容。
使用ng-if是一个好主意,在你要从服务器加载数据或图像的情况下,只显示那些取决于用户交互的情况。 这样你的页面加载将不会被不必要的密集任务所阻塞。
如果在ng-include和ng-controller上对ng-include会有很大的影响,那么ng-include将不会加载所需的部分,并且在ng-controller上的标志为真时不会进行处理,否则它不会加载控制器,除非标志是真正的,但问题是当一个标志在ng中为false时 – 如果标志变为真时它将从DOM中删除,在这种情况下它将重新加载DOM ng-show更好,一次性显示ng-if更好