什么时候支持ng-if和ng-show / ng-hide?


Answers:


703

取决于您的用例,但总结出不同之处:

  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-hide和时ng-if,可以使用动画,并且在Angular文档中都可以使用示例。

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


19
您可以将CSS3动画与一起使用ng-if。检查Animations段落和docs中的示例。另外,ng-hide/ng-show对于css选择器,像:first-child:nth-child不能正常工作,因为也会计算隐藏元素。
卢卡斯沃伊切霍夫斯基

4
angular.dart中的动画服务是相对较新的。在撰写本文时,尚不可用。
markovuksanovic 2014年

44
如果要使用指令(如ng-click)绑定处理程序,那么第一点就是没有问题。
凯文C.14年

9
另外,ng-if创建新作用域,ng-show但不创建新作用域。
马丁

8
还应该提到的是,如果经常执行操作,则从DOM中添加和删除元素会导致较高的性能成本。
凯文C.14年

130

请参见此处的CodePen,它演示了ng-if / ng-show在DOM方面的工作方式的差异。

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

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

Angular的编写非常好。考虑到它的作用,速度很快。但是它的作用是使困难的事情(如2路数据绑定)看起来很容易的一大堆魔术。使所有这些事情看起来容易,会带来一些性能开销。您可能会惊讶地发现,在一个$digest周期内,甚至没有人看过的DOM,评估了setter函数的成百上千次。然后您意识到您有数十或数百个不可见元素都在做同一件事...

桌面的确可能强大到足以解决大多数JS执行速度问题。但是,如果您是为移动设备开发的,那么只要有可能,使用ng-if就可以了。JS速度在移动处理器上仍然很重要。使用ng-if是一种非常简单的方法,可以以非常非常低的成本获得潜在的重大优化。


6
除上述答案外,非常好。给定一些良好的环境,这也有助于决策。谢谢。
肖恩

1
ng-show当您拥有多个选项卡(每个选项卡包含很多内容,需要花费很多时间渲染)时,此功能非常有用。第一次渲染后,选项卡之间的移动将是即时的,而ng-if这需要重新渲染,绑定事件等。您所说的缺点是,会在后台执行手表。迫切需要角度ng-ifshowwatch
豪华的

53

根据我的经验:

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将在编写控制器代码方面产生巨大的差异。


5
确实如此!ng-if不一定会使您的前端速度更快。这取决于您的需求。实际上,如果您在错误的情况下使用,则可能会出现其他情况。
Thiago C. S Ventura 2015年

1
但是根据我的说法,因为ng-if不会渲染到DOM上,所以与ng-show / hide相比它要快。我错了吗,请允许我在这一点上纠正。
Pardeep Jain

1
如果ng-if的值为假,则速度会更快,因为正如您所说,不需要将任何内容插入DOM。但是,如果这是真的,那么您就需要将可能非常复杂的元素插入DOM中。
Mawg说恢复Monica

“ 2)ng-if在评估为true / false时将创建/销毁作用域。如果您在ng-if上附加了控制器,则该控制器代码每次在执行“
Red Pea

35

答案并不简单:

它取决于目标计算机(移动设备还是台式机),取决于数据的性质,浏览器,操作系统,运行的硬件...如果您确实想知道,则需要进行基准测试。

这主要是内存与计算的问题...与大多数性能问题一样,这种差异在列表等重复元素(n)中会变得很明显,尤其是在嵌套(nxn或更糟)时,以及这些元素中运行哪种计算时

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

  • ng-if:如果相反,可能不会显示(稀疏)元素,则只需构建它们并实时销毁它们,尤其是在获取其内容昂贵(计算/分类/过滤,图像,生成图像)的情况下。这对于稀有或“按需”元素是理想的选择,它可以在不填充DOM的情况下节省内存,但会花费大量计算(创建/销毁元素)和带宽(获取远程内容)。它还取决于视图中的计算量(过滤/排序)与模型中已有的数据(预先排序/预先过滤的数据)之间的关系。


2
有关技术事实的其他答案。此为智慧。先生,您已经明确构建了非平凡的Angular应用!+1
华丽的

这个问题超出了角度,这是计算机科学中的一个基本问题,从某种意义上说,一种方法比另一种方法更有效。通常这可以通过一些基准测试来找到。:所以,你甚至可以一个方法,另一个取决于项目数之间的类似话题切换... math.stackexchange.com/questions/1632739/...
克里斯托夫鲁西研究所

12

重要说明:

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

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

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

因此,除非您运行太慢,否则要使用ngShow来保存头发。

无论如何,性能差异几乎没有引起注意,而且我不确定在没有测试的情况下它是谁的青睐...


8
$parent.scopevarngIf中使用数据绑定将纠正使用ngIf
meconroy 2014年

2
这不是完全正确的(就是@ user2173353的原始注释)。如果坚持良好做法,就不会遇到麻烦。这是一条非常基本的规则:“如果没有点,那说明您做错了”。有关其工作原理的演示,请参见此处:bit.ly/1SPv4wL。另一个很好的参考(请参见错误2):bit.ly/1QfFeWd >(我的指令将其模型值写入错误的范围。)这是不遵循上述做法的结果。
piotr.d 2015年

1
@ piotr.d没错,但这不是初学者可能需要关注的事情,还有另一种最佳实践,那就是把性能改进留到最后是更好的选择(尤其是性能改进可能不是现实中的改进) )。我见过ngIf无处不在的人们相信这将提高性能。这根本是不对的,并且不能说哪个是最好的,ngIf或者ngShow在特定情况下如果没有测试或深入分析就不能说是最好的。因此,我仍然建议您忘记使用ngIf,直到看到性能不佳或知道自己在做什么
user2173353 2015年

2
好点子。但是使用controllerAs使其成为非问题。例如,参见约翰·帕帕(John Papa)对controllerAs和vm的看法
jsruok '16

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


4

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

如果您使用ng-if该内容,则仅当ng-if表达式的计算结果为true时,才会加载内容。

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


这特别有用,因为即使CSS隐藏了DOM容器,大多数浏览器也会加载图像。他们通常只是寻找标签的src属性img,当标签被加载时!
Christophe Roussy 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.