何时支持ng-if与ng-show / ng-hide?

时间:2014-02-19 01:42:02

标签: angularjs angularjs-directive

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

是否有选择ng-if而不是ng-show / ng-hide或反之亦然的准则?

6 个答案:

答案 0 :(得分:686)

取决于您的使用案例,但总结一下差异:

  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
  4. ng-if相比,使用ng-show/ng-hide时,不在DOM中的元素对性能影响较小,您的网络应用可能会更快。根据我的经验,差异可以忽略不计。在同时使用ng-show/ng-hideng-if时都可以使用动画,并在Angular文档中提供示例。

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

答案 1 :(得分:130)

请参阅here了解一个CodePen,它展示了ng-if / ng-show的工作方式,DOM方面的差异。

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

  1. 由于某种原因,你需要数据绑定和$watch - 你的元素在它们不可见时保持活动状态。如果您希望能够检查当前不可见的输入的有效性,那么表单可能是一个很好的例子,以确定整个表单是否有效。
  2. 如上所述,您正在使用条件事件处理程序的一些非常精细的有状态逻辑。 那说,如果你发现自己手动附加和分离处理程序,这样当你使用ng-if时你就失去了重要的状态,问问自己这个状态是否会在数据模型中得到更好的表现,并且每当呈现元素时,处理程序通过指令有条件地应用。换句话说,处理程序的存在/不存在是状态数据的一种形式。从DOM中获取数据,并将其传输到模型中。处理程序的存在/不存在应由数据确定,因此易于重新创建。
  3. Angular写得非常好。考虑到它的作用,这很快。但它所做的是一大堆神奇的东西,使得硬件(如双向数据绑定)看起来很容易。让所有这些东西看起来很容易带来一些性能开销。您可能会惊讶地发现,在$digest周期内,在没有人看到的一大块DOM上,有多少数百或数千次的setter函数被评估。然后你意识到你已经有几十个或几百个看不见的元素做同样的事情......

    桌面可能确实足以使大多数JS执行速度问题没有实际意义。但是,如果你正在开发移动设备,那么使用ng-if,无论什么时候人性化,都应该是不费吹灰之力的。 JS速度在移动处理器上仍然很重要。使用ng-if是一种非常简单的方法,可以非常低的成本获得潜在的重要优化。

答案 2 :(得分:53)

根据我的经验:

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

2)ng-if会在评估为true / false时创建/销毁范围。如果你有一个连接到ng-if的控制器,那么每次ng-if评估为真时都会执行该控制器代码。如果您使用ng-show,则控制器代码仅执行一次。因此,如果您有一个在多个视图之间切换的按钮,则使用ng-if和ng-show会对您编写控制器代码的方式产生巨大影响。

答案 3 :(得分:34)

答案并不简单:

这取决于目标计算机(移动与桌面),它取决于数据的性质,浏览器,操作系统,运行的硬件......如果您真的想知道,则需要进行基准测试。

这主要是内存与计算问题......与大多数性能问题一样,重复元素(n)类似列表会产生重大差异,尤其是嵌套时(nxn,或更糟)以及你在这些元素中运行的计算:

  • ng-show :如果这些可选元素经常出现(密集),比如说90%的 时间,让它们准备好并且只显示/隐藏它们可能更快,特别是如果它们的内容便宜(只是纯文本,没有计算或加载)。这会消耗内存,因为它使用隐藏元素填充DOM,但只显示/隐藏已存在的内容可能是浏览器的廉价操作。

  • ng-if :如果相反的元素可能不会被显示(稀疏),只需构建它们并实时销毁它们,特别是如果它们的内容很昂贵(计算/排序/过滤,图像,生成的图像)​​。这是罕见或按需的理想选择。元素,它在不填充DOM方面节省了内存,但可能耗费大量计算(创建/销毁元素)和带宽(获取远程内容)。它还取决于您在视图中计算的数量(过滤/排序)与模型中已有的数量(预先排序/预过滤数据)。

答案 4 :(得分:12)

一个重要的注意事项:

ngIf(与ngShow不同)通常会创建可能产生意外结果的子范围。

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

(我的指示是将其模型值写入错误的范围。)

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

无论如何,性能上的差异几乎不可察觉,我不确定在没有测试的情况下对谁有利...

答案 5 :(得分:4)

ng-if如果使用ng-include和ng-controller将会产生重大影响 在ng-include上它不会加载所需的部分,除非flag为true,否则不会处理 在ng-controller上,除非flag为true,否则它不会加载控制器 但问题是当一个标志在ng中变错时 - 如果它在标志变为真时将从DOM中删除它将重新加载DOM在这种情况下ng-show更好,一次显示ng-if更好