我试图理解ng-if和ng-show/ng-hide之间的区别,但对我来说它们看起来是一样的。
在选择使用一种或另一种时,我应该记住有什么区别吗?
我试图理解ng-if和ng-show/ng-hide之间的区别,但对我来说它们看起来是一样的。
在选择使用一种或另一种时,我应该记住有什么区别吗?
当前回答
也许有趣的一点是,两者的优先级不同。
据我所知,ng-if指令是所有Angular指令中优先级最高(如果不是最高的话)的指令之一。这意味着:它将在所有其他低优先级的指令之前运行。事实上,它首先运行,意味着有效地,在任何内部指令被处理之前,元素被删除。至少,我是这么认为的。
I observerd and used this in the UI I'm building for my current customer. The entire UI is quite heavily packed, and it had ng-show and ng-hide all over it. Not to go into too much detail, but I built a generic component, which could be managed using JSON config, so I had to do some switching inside the template. There is an ng-repeat present, and inside the ng-repeat, a table is shown, which has a lot of ng-shows, ng-hides and even ng-switches present. They wanted to show at least 50 repeats in the list, which would result in more or less 1500-2000 directives to be resolved. I checked the code, and the Java backend + custom JS on the front would take about 150ms to process the data, and then Angular would chew some 2-3 seconds on it, before displaying. The customer did not complain, but I was appalled :-)
In my search, I stumbled across the ng-if directive. Now, maybe it's best to point out that at the point of conceiving this UI, there was no ng-if available. Because the ng-show and ng-hide had functions in them, which returned booleans, I could easily replace them all with ng-if. By doing so, all inner directives seemed to be no longer evaluated. That meant that I dropped back to about a third of all directives being evaluated, and thus, the UI speeded up to about 500ms - 1 sec loading time. (I have no way to determine exact seconds)
注意:指令没有被评估的事实,是对下面发生的事情的一个有根据的猜测。
所以,在我看来:如果你需要元素出现在页面上(即:检查元素,或其他),但只是被隐藏,请使用ng-show/ng-hide。在所有其他情况下,使用ng-if。
其他回答
也许有趣的一点是,两者的优先级不同。
据我所知,ng-if指令是所有Angular指令中优先级最高(如果不是最高的话)的指令之一。这意味着:它将在所有其他低优先级的指令之前运行。事实上,它首先运行,意味着有效地,在任何内部指令被处理之前,元素被删除。至少,我是这么认为的。
I observerd and used this in the UI I'm building for my current customer. The entire UI is quite heavily packed, and it had ng-show and ng-hide all over it. Not to go into too much detail, but I built a generic component, which could be managed using JSON config, so I had to do some switching inside the template. There is an ng-repeat present, and inside the ng-repeat, a table is shown, which has a lot of ng-shows, ng-hides and even ng-switches present. They wanted to show at least 50 repeats in the list, which would result in more or less 1500-2000 directives to be resolved. I checked the code, and the Java backend + custom JS on the front would take about 150ms to process the data, and then Angular would chew some 2-3 seconds on it, before displaying. The customer did not complain, but I was appalled :-)
In my search, I stumbled across the ng-if directive. Now, maybe it's best to point out that at the point of conceiving this UI, there was no ng-if available. Because the ng-show and ng-hide had functions in them, which returned booleans, I could easily replace them all with ng-if. By doing so, all inner directives seemed to be no longer evaluated. That meant that I dropped back to about a third of all directives being evaluated, and thus, the UI speeded up to about 500ms - 1 sec loading time. (I have no way to determine exact seconds)
注意:指令没有被评估的事实,是对下面发生的事情的一个有根据的猜测。
所以,在我看来:如果你需要元素出现在页面上(即:检查元素,或其他),但只是被隐藏,请使用ng-show/ng-hide。在所有其他情况下,使用ng-if。
ng-if指令从页面中删除内容,ng-show/ng-hide使用CSS的display属性隐藏内容。
如果您想使用:first-child和:last-child伪选择器来设置样式,这是非常有用的。
事实上,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-show通过css隐藏内容,是的,但它导致了奇怪的小故障在div的应该是按钮。
我有一个底部有两个按钮的卡,根据实际状态,一个与第三个交换,示例编辑按钮与新条目。使用ng-show=false来隐藏左边的按钮(首先出现在文件中),下面的按钮的右边框出现在卡片外面。 Ng-if通过完全不包括代码来修复这个问题。 (只是在这里检查是否有一些隐藏的惊喜使用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.
原因是输入字段是存在的,它是必需的,但由于它是隐藏的Chrome不能关注它。这可能会破坏您的代码,因为此错误会停止脚本执行。所以要小心!