我试图了解ng-if
和ng-show
/ 的区别ng-hide
,但对我来说它们看起来相同。
我应该记住使用一个或另一个来区别吗?
我试图了解ng-if
和ng-show
/ 的区别ng-hide
,但对我来说它们看起来相同。
我应该记住使用一个或另一个来区别吗?
Answers:
该ngIf
指令根据表达式删除或重新创建 DOM树的一部分。如果赋值为的表达式ngIf
的值为假,则将元素从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
指令显示或隐藏基于提供给所述表达给定的HTML元素ngShow
属性。通过删除ng-hide
CSS类或将CSS类添加到元素,可以显示或隐藏该元素。的.ng-hide
CSS类在AngularJS预先定义并设定的显示样式为无(使用!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
表达式求false
则ng-hide
CSS类被添加到class
所述元件上的属性使其成为隐藏。如果为true
,ng-hide
则从元素中删除CSS类,从而使该元素不会显示为隐藏。
data.input
它如何/为什么起作用……但是data
仅在模型中不起作用。@CodeHater
ngIf
创建一个新的作用域,因此,即使父作用域中存在具有相同名称的模型,嵌套的上方示例ngModel
也会创建一个新data
模型。但是,当您使用点表示法时,将使JS查找范围的原型链。因此,如果它在当前作用域中找不到该值,它将尝试在父作用域中寻找它,依此类推。创造一个不同的范围内很少有其他的指令是ngInclude
,ngRepeat
。希望现在清除。:)
也许有趣的一点是两者之间的优先级之间的差异。
据我所知,ng-if指令具有所有Angular指令中最高(如果不是最高)的优先级之一。这意味着:它将先于所有其他优先级较低的指令运行。它首先运行的事实意味着有效地在处理任何内部指令之前将元素删除。或至少:这就是我所做的。
我在为当前客户建立的用户界面中观察并使用了它。整个用户界面非常拥挤,并且整个屏幕上都有ng-show和ng-hide。不必赘述,但我构建了一个通用组件,可以使用JSON配置对其进行管理,因此我必须在模板内部进行一些切换。存在一个ng-repeat,并且在ng-repeat内显示了一个表格,其中包含许多ng-show,ng-hide和ng-switch。他们希望在列表中至少显示50个重复,这将导致解决大约1500-2000条指令。我检查了代码,前面的Java后端+自定义JS大约需要150毫秒来处理数据,然后Angular会在显示之前咀嚼2-3秒。客户没有抱怨,但我感到震惊:-)
在搜索中,我偶然发现了ng-if指令。现在,也许最好指出,在构想此UI时,尚无ng-if。因为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
伪选择款式。
:first-child
and :last-child
developer.mozilla.org/en-US/docs/Web/CSS/:first-child developer.mozilla.org/en-US/docs/Web/CSS/:last-child
关于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=预览
希望这个例子可以帮助您理解范围。尝试为ng-show和ng-if提供错误的值,并在控制台中检查DOM。尝试在输入框中输入值,然后观察差异。
<!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
,它创建了自己的作用域,导致了有趣的实际区别:
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
ng-if如果为false,则会从DOM中删除元素。这意味着所有与这些元素相关的事件和指令都将丢失。例如,ng-click到子元素之一,当ng-if评估为false时,将从DOM中删除该元素,并在它为true时再次创建它。
ng-show / ng-hide不会从DOM中删除元素。它使用CSS样式(.ng-hide)来隐藏/显示元素。这样,您的事件,附加到子代的指令将不会丢失。
ng-if创建子作用域,而ng-show / ng-hide不创建子作用域。
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.
ng-if和ng-show的一个有趣的区别是:
安全
如果ng-if块中存在的DOM元素的值为false,则不会呈现该元素
在进行ng-show的情况下,用户可以打开您的“检查元素窗口”并将其值设置为TRUE。
而且,随着声音的泛滥,原本应该隐藏的全部内容也会被显示出来,这是安全漏洞。:)
ng-if
模型本身的HTML元素ng-model
,不再添加由添加的。