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

Pat*_*lin 511 angularjs angularjs-directive

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

有没有对选择的准则ng-ifng-show/ ng-hide或反之亦然?

mar*_*vic 697

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

  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相比,您的Web应用程序在使用时可能看起来更快ng-show/ng-hide.根据我的经验,差异可以忽略不计.动画同时使用时是可能的ng-show/ng-hideng-if,与两者的角文档中的例子.

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

  • 如果您正在使用指令(如ng-click)来绑定处理程序,那么您的第一点就不是问题. (44认同)
  • 您可以将CSS3动画与`ng-if`一起使用.检查Animations段落和[docs](http://docs.angularjs.org/api/ng/directive/ngIf)中的示例.同样使用`ng-hide/ng-show`,css选择器如`:first-child`或`:nth-​​child`将无法正常工作,因为隐藏的元素也将被计算. (19认同)
  • 此外,`ng-if`创建了一个新范围,而`ng-show`则没有. (8认同)
  • 还应该提到的是,如果经常进行,从DOM中添加和删除元素会导致高性能成本. (8认同)
  • angular.dart中的动画服务相对较新.在撰写本文时,它无法使用. (4认同)

XML*_*XML 130

请参阅此处了解CodePen,它展示了ng-if/ng-show如何工作的差异,DOM-wise.

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

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

Angular写得非常好.考虑到它的作用,这很快.但它所做的是一大堆神奇的东西,使得硬件(如双向数据绑定)看起来很容易.让所有这些东西看起来很容易带来一些性能开销.你可能会惊讶地发现,$digest在一个没有人看过的大块DOM 的循环中,一个setter函数被评估了几百或几千次.然后你意识到你有几十个或几百个看不见的元素都在做同样的事情......

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

  • 除上述答案外,还有很好的补充.给出一些良好的背景,这也有助于决策.谢谢. (6认同)

Yi *_*i Z 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会对编写控制器代码的方式产生巨大影响.

  • 这是一个巨大的真实!ng-if不一定能让你的前端更快.这取决于您的需求.实际上如果你在错误的情况下使用它可能会反过来. (5认同)

Chr*_*ssy 35

答案并不简单:

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

它主要是一个内存与计算问题......与大多数性能问题一样,重复元素(n)之类的差异可能变得很重要,特别是在嵌套(nxn或更差)时,以及这些元素中运行的是什么类型的计算:

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

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

  • 技术事实的其他答案.这一个用于智慧.您已经明确构建了非平凡的Angular应用程序先生!+1 (2认同)

use*_*353 12

一个重要的说明:

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

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

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

因此,为了保存你的头发,只需使用ngShow,除非你跑得太慢.

无论如何,性能差异几乎不可察觉,如果没有测试我还不确定谁有利于它...

  • 在*ngIf*中的数据绑定中使用`$ parent.scopevar`将在使用*ngIf*时纠正子范围问题 (8认同)
  • 这不完全正确(原来@ user2173353的评论,即).如果你坚持良好的做法,你就不会遇到麻烦.这是一个非常基本的规则:"如果没有点,你做错了".请参阅此处,了解其工作原理:http://bit.ly/1SPv4wL.另一个很好的参考(参见错误#2):http://bit.ly/1QfFeWd>(我的指令是将其模型值写入错误的范围.)这是不坚持上述做法的结果. (2认同)
  • 好点子.但是使用控制器使这成为一个问题.例如,参见[John Papa对控制器AS和vm的看法](http://www.johnpapa.net/angularjss-controller-as-and-the-vm-variable/). (2认同)

app*_*oid 5

如果您使用ng-show or ng-hide内容(例如来自服务器的缩略图),则无论表达式的值如何都将加载,但将根据表达式的值显示。

如果您使用ng-if,则仅当 ng-if 的表达式评估为真时才会加载内容。

在您要从服务器加载数据或图像并仅根据用户交互显示它们的情况下,使用 ng-if 是一个好主意。这样您的页面加载就不会被不必要的 nw 密集型任务阻塞。