ng-if和ng-show / ng-hide有什么区别?
我想了解ng-if
和ng-show
/ ng-hide
之间的区别,但是它们看起来和我一样。
有没有区别,我应该记住select使用一个或另一个?
ngIf
ngIf
指令根据ngIf
删除或重新创build一部分DOM树。 如果赋值为ngIf
的expression式的值为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
删除元素时,如果其作用域被销毁,并且在元素被恢复时创build新的作用域。 ngIf
创build的范围使用原型inheritance从其父范围inheritance。
如果在ngModel
中使用ngIf
绑定到父范围中定义的JavaScript基元,则对子范围内的variables进行的任何修改都不会影响父范围中的值,例如
<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
variables引用父级作用域对象:
<input type="text" ng-model="data"> <div ng-if="true"> <input type="text" ng-model="$parent.data"> </div>
ngShow
ngShow
指令根据提供给ngShow
属性的expression式显示或隐藏给定的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
expression式的计算结果为false
那么ng-hide
CSS类将被添加到元素的class
属性中,从而使其隐藏起来。 如果为true
,则将ng-hide
CSS类从元素中移除,导致该元素不显示为隐藏状态。
也许有趣的一点是两者之间的优先级之间的差异。
据我所知,ng-if指令是所有Angular指令中最高(如果不是最高的)优先级之一。 这意味着:它将在所有其他优先级较低的指令之前运行。 它运行FIRST的事实意味着,在处理任何内部指令之前,该元素将被有效地移除。 或者至less:这就是我所做的。
我观察并在用户界面中使用了这个function。 整个用户界面是非常严重的,它已经在其上显示和隐藏。 不要深入细节,但是我构build了一个通用组件,可以使用JSONconfiguration进行pipe理,所以我不得不在模板中进行一些切换。 现在有一个ng-repeat,在ng-repeat内部显示一个表格,其中有很多ng-shows,ng-hides甚至ng-switch。 他们希望在列表中至less显示50次重复,这将导致或多或less地解决1500-2000个指令。 我检查了代码,前端的Java后端+自定义JS需要大约150ms来处理数据,然后Angular会在显示前咀嚼大约2-3秒。 客户没有抱怨,但我很惊讶:-)
在我的search中,我偶然发现了ng-if指令。 现在,也许最好指出,在构思这个UI的时候,没有可用的ng。 因为ng-show和ng-hide在其中有返回布尔值的函数,所以我很容易用ng-if来replace它们。 通过这样做,所有内部指令似乎不再被评估。 这意味着我减less了大约三分之一的被评估的指令,因此UI的加速时间大约为500ms – 1秒。 (我无法确定确切的秒数)
请注意:指令没有被评估的事实是对下面发生的事情的有根据的猜测。
所以,在我看来:如果你需要元素出现在页面上(即:检查元素,或其他),但只是隐藏,使用ng-show / ng-hide。 在所有其他情况下,使用ng-if。
ng-if
指令从页面中删除内容,而ng-show/ng-hide
使用CSS display
属性来隐藏内容。
如果要使用:first-child
和:last-child
伪select器进行样式,这很有用。
@EdSpencer是正确的。 如果你有很多元素,而且你使用ng-if只是实例化相关的元素,那么你正在节省资源。 @CodeHater也是有点正确的,如果你要经常移除和显示一个元素,隐藏它而不是移除它可以提高性能。
我发现的ng-if的主要用例是,如果内容是非法的,它允许我干净地validation和消除一个元素。 例如,我可以引用一个空的图像名称variables,这将抛出一个错误,但如果我ng-if,并检查是否为空,这一切都很好。 如果我做了一个ng显示,错误仍然会触发。
@Gajus Kuizinas和@CodeHater是正确的。 这里我只是举个例子。 当我们使用ng-if时,如果赋值为false,那么整个html元素将从DOM中删除。 如果赋值为true,那么html元素将在DOM上可见。 与父范围相比,范围将有所不同。 但是在ng显示的情况下,只能根据赋值显示和隐藏元素。 但它始终停留在DOM中。 只有可见性会根据指定的值发生变化。
http://plnkr.co/edit/3G0V9ivUzzc8kpLb1OQn?p=preview
希望这个例子能帮助你理解范围。 尝试给ng-show和ng-if赋予错误的值,并在控制台中检查DOM。 尝试在input框中input值并观察差异。
<!DOCTYPE html>
你好!
<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-if和ng-show的一个重要的注意事项是,当使用表单控件时,最好使用ng-if
因为它完全从dom中移除元素。
这种差异非常重要,因为如果您创build一个带有required="true"
的input字段,然后设置ng-show="false"
来隐藏它,Chrome会在用户尝试提交表单时抛出以下错误:
An invalid form control with name='' is not focusable.
作为input字段的原因是存在的,这是required
但因为它是隐藏的Chrome不能专注于它。 这可以从字面上打破你的代码,因为这个错误暂停脚本执行。 所以要小心!
-
ng-if if false将从DOM中删除元素。 这意味着所有的事件,这些元素所附的指令都将丢失。 例如,ng-click对其中一个子元素,当ng-if的计算结果为false时,该元素将被从DOM中移除,当它为真时,再次被重新创build。
-
ng-show / ng-hide不会删除DOM中的元素。 它使用CSS样式(.ng-hide)来隐藏/显示元素。这样,你的事件,附属于孩子的指令就不会丢失。
-
ng-if创build一个子范围,而ng-show / ng-hide则不创build子范围。
要注意的是,现在发生在我身上的一件事:ng-show确实通过css隐藏了内容,是的,但是它导致div中的怪异毛刺被认为是button。
我有一个底部有两个button的卡,根据实际状态,用第三个示例编辑button与新条目交换。 使用ng-show = false来隐藏左边的文件(出现在文件的第一个文件中),碰巧下面的button结束了卡的右边界。 ng-if修复了根本不包含代码的情况。 (只是在这里检查,如果有一些隐藏的意外使用ng-if而不是ng-show)
ng-show和ng-hide以相反的方式工作。 但是,如果我们使用ng-if,那么ng-hide或ng-show与ng-if之间的区别将会完全隐藏,如果我们使用ng-if元素将会在dom中创build但是使用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.
事实上,与ng-show
不同, ng-if
指令创build了自己的范围,导致了有趣的实际区别:
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>
ng-if和ng-show的一个有趣的区别是:
安全
存在于ng-if块中的DOM元素在其值为假的情况下将不被呈现
在ng显示的情况下,用户可以打开你的Inspect Element窗口并将其值设置为TRUE。
而且,随着一声巨响,整个内容被隐藏起来,这是一个安全漏洞。 🙂