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

Ste*_*and 422 angularjs angularjs-ng-show angularjs-ng-if

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

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

Alw*_*ner 513

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>
Run Code Online (Sandbox Code Playgroud)

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

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

<input type="text" ng-model="data">
<div ng-if="true">
    <input type="text" ng-model="data">
</div>        
Run Code Online (Sandbox Code Playgroud)

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

<input type="text" ng-model="data.input">
<div ng-if="true">
    <input type="text" ng-model="data.input">
</div>
Run Code Online (Sandbox Code Playgroud)

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

<input type="text" ng-model="data">
<div ng-if="true">
    <input type="text" ng-model="$parent.data">
</div>
Run Code Online (Sandbox Code Playgroud)

ngShow

ngShow指令根据提供给属性的表达式显示或隐藏给定的HTML元素ngShow.通过在元素上删除或添加ng-hideCSS类来显示或隐藏元素.的.ng-hideCSS类在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>
Run Code Online (Sandbox Code Playgroud)

ngShow表达式求值时false,ng-hideCSS类被添加到class元素上的属性,导致它被隐藏.何时true,ng-hide从元素中删除CSS类,导致元素不显示为隐藏.

  • 提示:通过"ng-if"删除HTML元素本身,由"ng-model"添加的模型不再存在. (31认同)
  • @mcpDESIGNS`ngIf`创建一个新的范围,因此查看上面的示例嵌套的`ngModel`将创建一个新的`data`模型,即使父范围中存在具有相同名称的模型.但是当你使用点符号时,你会让JS查找范围的原型链.因此,如果它没有在当前作用域中找到该值,它将尝试在父作用域中查找它,依此类推.很少有其他创建不同范围的指令是`ngInclude`,`ngRepeat`.希望现在清楚.:) (7认同)
  • @CodeHater我已经成功地利用ng-if over ng-show/ng-hide在一个原本会有大dom的页面上.它似乎使页面_feel_更快,但绝不是科学分析. (3认同)
  • 哪一个更适合性能?我认为ng-show和ng-hide不是吗? (3认同)

gjo*_*ris 96

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

据我所知,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.


And*_*rei 36

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

这在您想要使用:first-child:last-child伪选择器进行样式的情况下很有用.


pep*_*dip 16

@EdSpencer是对的.如果你有很多的元素,你就可以只实例相关的,你是节约资源使用,如果NG-.@CodeHater也有些是正确的,如果你要经常删除,并显示一个元素,隐藏它,而不是删除它可以提高性能.

主要使用情况下,我找到NG-如果是,它让我可以清晰地验证,如果内容是非法的eliminte的元素.比如我可以引用到一个空图像名称的变量,这将抛出一个错误,但如果我NG-如果和检查它是否是空,这一切都很好.如果我做了ng-show,那么错误仍然会触发.


sup*_*san 7

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

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

An invalid form control with name='' is not focusable.
Run Code Online (Sandbox Code Playgroud)

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


小智 5

@ 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>
Run Code Online (Sandbox Code Playgroud)

你好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}}
Run Code Online (Sandbox Code Playgroud)