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

在选择使用一种或另一种时,我应该记住有什么区别吗?


当前回答

ng-if if false will remove elements from DOM. This means that all your events, directives attached to those elements will be lost. For example, ng-click to one of child elements, when ng-if evaluates to false, that element will be removed from DOM and again when it is true it is recreated. ng-show/ng-hide does not remove the elements from DOM. It uses CSS styles (.ng-hide) to hide/show elements .This way your events, directives that were attached to children will not be lost. ng-if creates a child scope while ng-show/ng-hide does not.

其他回答

ng-if if false will remove elements from DOM. This means that all your events, directives attached to those elements will be lost. For example, ng-click to one of child elements, when ng-if evaluates to false, that element will be removed from DOM and again when it is true it is recreated. ng-show/ng-hide does not remove the elements from DOM. It uses CSS styles (.ng-hide) to hide/show elements .This way your events, directives that were attached to children will not be lost. ng-if creates a child scope while ng-show/ng-hide does not.

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中创建的作用域使用原型继承继承父作用域。

如果ngIf中使用ngModel绑定到父作用域中定义的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(使用!重要标志)。

<!-- 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类将从元素中移除,使元素不显示为隐藏状态。

事实上,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事件,显示变量,从内部/自己的作用域,被改变了,但ng-if正在观察从外部作用域同名的另一个变量,所以解决方案不工作。对于ng-show,我们只有一个show变量,这就是它工作的原因。要修复第一次尝试,我们应该通过$parent.show引用show from parent/outer scope。

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

这个区别很重要,因为如果你创建了一个required="true"的输入字段,然后设置ng-show="false"来隐藏它,当用户试图提交表单时,Chrome会抛出以下错误:

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

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

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

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