繁体   English   中英

ng-if和ng-show / ng-hide有什么区别

[英]What is the difference between ng-if and ng-show/ng-hide

我试图理解ng-ifng-show / ng-hide之间的区别,但它们看起来和我一样。

我是否应该记住选择使用其中一种?

ngIf

ngIf指令根据ngIf 删除或重新创建 DOM树的一部分。 如果分配给ngIf的表达式求值为false值,则从DOM中删除该元素,否则将该元素的克隆重新插入到DOM中。

<!-- when $scope.myValue is truthy (element is restored) -->
<div ng-if="1"></div>

<!-- when $scope.myValue is falsy (element is removed) -->
<div ng-if="0"></div>

使用ngIf删除元素时,其范围将被销毁,并且在还原元素时会创建新范围。 ngIf创建的作用域使用原型继承从其父作用域继承。

如果在ngModel中使用ngIf绑定到父作用域中定义的JavaScript原语,则对子作用域内的变量所做的任何修改都不会影响父作用域中的值,例如

<input type="text" ng-model="data">
<div ng-if="true">
    <input type="text" ng-model="data">
</div>        

要绕过这种情况并从子作用域内部更新父作用域中的模型,请使用对象:

<input type="text" ng-model="data.input">
<div ng-if="true">
    <input type="text" ng-model="data.input">
</div>

或者, $parent变量引用父作用域对象:

<input type="text" ng-model="data">
<div ng-if="true">
    <input type="text" ng-model="$parent.data">
</div>

ngShow

ngShow指令根据提供给ngShow属性的表达式显示或隐藏给定的HTML元素。 通过在元素上移除或添加ng-hide CSS类来显示或隐藏元素。 .ng-hide CSS类在AngularJS中预定义,并将显示样式设置为none(使用!important标志)。

<!-- when $scope.myValue is truthy (element is visible) -->
<div ng-show="1"></div>

<!-- when $scope.myValue is falsy (element is hidden) -->
<div ng-show="0" class="ng-hide"></div>

ngShow表达式求值为falseng-hide CSS类将添加到元素的class属性中,从而导致其隐藏。 如果为true ,则从元素中删除ng-hide CSS类,导致元素不显示为隐藏。

也许一个有趣的观点是两者之间的优先级之间的差异。

据我所知,ng-if指令具​​有所有Angular指令中最高(如果不是最高)优先级之一。 这意味着:它将在所有其他更低优先级指令之前运行FIRST。 它运行FIRST的事实意味着有效地,在处理任何内部指令之前删除该元素。 或者至少:这就是我所做的。

我观察并在我正在为当前客户构建的UI中使用它。 整个用户界面非常庞大,并且整个界面都有ng-show和ng-hide。 不要过多细节,但我构建了一个通用组件,可以使用JSON配置进行管理,所以我不得不在模板中进行一些切换。 存在ng-repeat,并且在ng-repeat内部显示了一个表格,其中包含大量的ng-shows,ng-hides甚至ng-switch。 他们希望在列表中显示至少50个重复,这将导致或多或少的1500-2000指令得到解决。 我检查了代码,前面的Java后端+自定义JS需要大约150ms来处理数据,然后Angular会在显示之前咀嚼2-3秒。 客户没有抱怨,但我感到震惊:-)

在我的搜索中,我偶然发现了ng-if指令。 现在,也许最好指出,在构思这个用户界面时,没有ng-如果可用的话。 因为ng-show和ng-hide具有返回布尔值的功能,所以我可以用ng-if轻松替换它们。 通过这样做,似乎不再评估所有内部指令。 这意味着我退回到所评估的所有指令的大约三分之一,因此,UI加速到大约500毫秒 - 加载时间为1秒。 (我无法确定确切的秒数)

请注意:指令未被评估的事实是对下面发生的事情的有根据的猜测。

因此,在我看来:如果您需要在页面上显示元素(即:用于检查元素或其他),只需隐藏,请使用ng-show / ng-hide。 在所有其他情况下,使用ng-if。

ng-if指令从页面中删除内容, ng-show/ng-hide使用CSS display属性隐藏内容。

如果您想使用:first-child:last-child伪选择器来设置样式,这非常有用。

@EdSpencer是对的。 如果你有很多元素并且你使用ng-if只实例化相关元素,那么你就节省了资源。 @CodeHater也有些正确,如果您要经常删除并显示元素,隐藏它而不是删除它可以提高性能。

我发现ng-if的主要用例是,如果内容是非法的,它允许我干净地验证和删除元素。 例如,我可以引用一个空图像名称变量,这将抛出一个错误,但如果我在 - 并且检查它是否为空,那一切都很好。 如果我做了ng-show,那么错误仍然会触发。

关于ng-if和ng-show的一个重要注意事项是,当使用表单控件时,最好使用ng-if因为它完全从dom中删除了元素。

这种差异非常重要,因为如果您使用required="true"创建输入字段,然后设置ng-show="false"来隐藏它,Chrome会在用户尝试提交表单时抛出以下错误:

An invalid form control with name='' is not focusable.

原因是输入字段存在并且是required但由于隐藏了Chrome,因此无法关注它。 这可能会破坏您的代码,因为此错误会停止脚本执行。 所以要小心!

@ Gajus Kuizinas和@CodeHater都是对的。 我在这里举个例子。 当我们使用ng-if时,如果指定的值为false,那么整个html元素将从DOM中删除。 如果赋值为true,那么html元素将在DOM上可见。 与父范围相比,范围将有所不同。 但是在ng-show的情况下,它只会根据指定的值显示和隐藏元素。 但它总是留在DOM中。 只有可见性根据指定的值更改。

http://plnkr.co/edit/3G0V9ivUzzc8kpLb1OQn?p=preview

希望这个例子能帮助你理解范围。 尝试给ng-show和ng-if提供错误值,并在控制台中检查DOM。 尝试在输入框中输入值并观察差异。

<!DOCTYPE html>

你好Plunker!

<input type="text" ng-model="data">
<div ng-show="true">
    <br/>ng-show=true :: <br/><input type="text" ng-model="data">
</div>
<div ng-if="true">
    <br/>ng-if=true :: <br/><input type="text" ng-model="data">
</div> 
{{data}}

事实上,与ng-show不同, ng-if指令创建了自己的范围,导致了有趣的实际差异:

 angular.module('app', []).controller('ctrl', function($scope){ $scope.delete = function(array, item){ array.splice(array.indexOf(item), 1); } }) 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app='app' ng-controller='ctrl'> <h4>ng-if:</h4> <ul ng-init='arr1 = [1,2,3]'> <li ng-repeat='x in arr1'> {{show}} <button ng-if='!show' ng-click='show=!show'>Delete {{show}}</button> <button ng-if='show' ng-click='delete(arr1, x)'>Yes {{show}}</button> <button ng-if='show' ng-click='show=!show'>No</button> </li> </ul> <h4>ng-show:</h4> <ul ng-init='arr2 = [1,2,3]'> <li ng-repeat='x in arr2'> {{show}} <button ng-show='!show' ng-click='show=!show'>Delete {{show}}</button> <button ng-show='show' ng-click='delete(arr2, x)'>Yes {{show}}</button> <button ng-show='show' ng-click='show=!show'>No</button> </li> </ul> <h4>ng-if with $parent:</h4> <ul ng-init='arr3 = [1,2,3]'> <li ng-repeat='item in arr3'> {{show}} <button ng-if='!show' ng-click='$parent.show=!$parent.show'>Delete {{$parent.show}}</button> <button ng-if='show' ng-click='delete(arr3, x)'>Yes {{$parent.show}}</button> <button ng-if='show' ng-click='$parent.show=!$parent.show'>No</button> </li> </ul> </div> 

在第一个列表中, on-click事件, show变量,从内在/自己的范围,更改,但ng-if正在观察具有相同名称的外部范围的另一个变量,因此解决方案不起作用。 ng-show情况下,我们只有一个show变量,这就是它工作的原因。 要解决的第一次尝试,我们应该参照show从通过父/外部范围$parent.show

  1. ng-if if false将从DOM中删除元素。 这意味着您的所有事件,附加到这些元素的指令都将丢失。 例如,ng-click到其中一个子元素,当ng-if计算结果为false时,该元素将从DOM中删除,如果为true,则重新创建它。

  2. ng-show / ng-hide不会从DOM中删除元素。 它使用CSS样式(.ng-hide)隐藏/显示元素。这样,您的事件,附加到子项的指令不会丢失。

  3. ng-if创建子范围,而ng-show / ng-hide则不创建子范围。

要注意,现在发生在我身上的事情:ng-show确实通过css隐藏了内容,是的,但它导致了div应该是按钮的奇怪故障。

我有一张卡片,底部有两个按钮,根据实际状态,一个用第三个示例编辑按钮与新条目交换。 使用ng-show = false来隐藏左边的一个(在文件中首先出现),发生了以下按钮最终在卡外面的右边框。 ng-if通过不包括代码来修复它。 (如果有一些隐藏的惊喜使用ng-if而不是ng-show,请检查这里)

ng-show和ng-hide以相反的方式工作。 但ng-hide或ng-show与ng-if之间的区别在于,如果我们使用ng-if那么元素将在dom中创建但是使用ng-hide / ng-show元素将完全隐藏。

ng-show=true/ng-hide=false:
Element will be displayed

ng-show=false/ng-hide=true:
element will be hidden

ng-if =true
element will be created

ng-if= false
element will be created in the dom. 

ngIf通过删除或重新创建元素来对DOM进行操作。

ngShow应用css规则来隐藏/显示事物。

对于大多数情况(并非总是如此) ,我总结一下,如果您需要一次性检查以显示/隐藏内容,请使用ng-if ,如果您需要根据屏幕上的用户操作显示/隐藏内容(如选中复选框然后显示文本框,取消选中然后隐藏文本框等...),然后使用ng-show

ng-if和ng-show的一个有趣的区别是:

安全

如果其值为false,则不会呈现ng-if块中存在的DOM元素

在ng-show的情况下,用户可以打开Inspect Element Window并将其值设置为TRUE。

并且使用whoop,显示要隐藏的整个内容,这是一个安全漏洞。 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM