什么时候更喜欢ng-if和ng-show/ng-hide?

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

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

225370 次浏览

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

  1. ng-if将从DOM中删除元素。这意味着所有附加到这些元素的处理程序或其他任何东西都将丢失。例如,如果您将一个单击处理程序绑定到一子元素,当ng-if计算结果为false时,该元素将从DOM中移除,并且您的单击处理程序将不再工作,即使ng-if后来计算结果为true并显示该元素。您需要重新连接处理程序。
  2. ng-show/ng-hide不会从DOM中删除元素。它使用CSS样式来隐藏/显示元素(注意:您可能需要添加自己的类)。这样,您与儿童联系的处理人员就不会丢失。
  3. ng-if创建子作用域,而ng-show/ng-hide没有

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

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

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

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

  1. 由于某些原因,您需要元素上的数据绑定和$watch-es在它们不可见时保持活动。如果您希望能够检查当前不可见的输入的有效性,以确定整个表单是否有效,那么表单可能是一个很好的例子。
  2. 如上所述,您正在使用一些带有条件事件处理程序的非常复杂的有状态逻辑。也就是说,如果您发现自己手动附加和分离处理程序,以至于在使用ng-if时丢失了重要的状态,那么请问问自己,这种状态是否可以更好地表示在数据模型中,以及在元素呈现时由指令有条件地应用处理程序。换句话说,处理程序的存在/缺失是状态数据的一种形式。将数据从DOM中取出,并放入一个模型中。处理程序的存在/不存在应该由数据决定,因此很容易重新创建。

Angular写得非常好。考虑到它的功能,它的速度很快。但它所做的是一大堆神奇的事情,让困难的事情(比如双向数据绑定)看起来简单得微不足道。为了让所有这些事情看起来都很简单,需要一些性能开销。您可能会惊讶地发现,在$digest循环期间,一个setter函数在一大块甚至没有人看过的DOM上被求值了多少次。然后你意识到你有几十个或数百个看不见的元素都在做同样的事情……

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

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 or ng-hide的内容(例如。来自服务器的缩略图)将被加载,而不管表达式的值,但将根据表达式的值显示。

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

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

答案并不简单:

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

这主要是内存和计算的问题…与大多数性能问题一样,使用重复的元素 (n)之类的列表时,差异可能变得显著,特别是当嵌套的 (n x n,或更糟)时,以及你在里面运行的计算中这些元素的类型:

  • ng-show:如果这些可选元素经常出现(密集),比如90% 时间,它可能会更快地准备好它们,只显示/隐藏它们,特别是如果它们的内容是廉价的(只是纯文本,不需要计算或加载)。当它用隐藏元素填充DOM时,这会消耗内存,但是仅仅显示/隐藏已经存在的东西对浏览器来说可能是一个廉价的操作

  • ng-if:如果相反,元素可能不会被显示(稀疏),那么就实时构建它们并销毁它们,特别是如果它们的内容获取成本很高(计算/排序/过滤,图像,生成图像)。这对于稀有或“随需应变”的元素来说是理想的,它节省了内存,不填充DOM,但会花费大量的计算(创建/销毁元素)和带宽(获取远程内容)。这也取决于你在视图中计算了多少(过滤/排序)和你在模型中已经有了多少(预排序/预过滤的数据)。