在 AngularJS 1 中,如果想切换DOM元素的显示状态,估计你会用 AngularJS 1 内置的指令如: ng-show 或者 ng-hide :
AngularJS 1 示例:
<div ng-show="showGreeting"> Hello, there! </div>
而 angular2 里,新的模版语法允许你将表达式绑定到DOM元素的任何原生属性上。 这个绝对牛逼的功能带来了无限的可能。其中一项就是绑定表达式到原生的 hidden 属性上,和 ng-show 有点像,也是为元素设置 display: none :
angular2 的 [hidden] 示例(不推荐):
<div [hidden]="!showGreeting"> Hello, there! </div>
第一眼看上面的例子,似乎就是 AngularJS 1 里的 ng-show 。其实不然,她们有着 !important 的不同。
ng-show 和 ng-hide 都是通过一个叫 ng-hide 的CSS class来控制 DOM 元素的显示状态, ng-hide class就是简单的把元素设置成 display: none 。这里的关键在于, AngularJS 1 在 ng-hide class里增加了 !important ,用来调整该class的优先级,使得它能够覆盖来自其他样式对该元素 display 属性的赋值。
再来说回本例,原生 hidden 属性上的 display: none 样式是由浏览器实现的。大多数浏览器是不会用 !important 来调整其优先级的。因此,通过 [hidden]="expression" 来控制元素显示状态就很容易意外的被其他样式覆盖掉。举个例子:如果我在其他地方对这个元素写了这样一个样式 display: flex ,这就比原生 hidden 属性的优先级高( 看这里 )。
基于这个原因,我们通常使用 *ngIf 切换元素存在状态来完成相同目标:
angular2 的 *ngIf 示例(推荐):
<div *ngIf="showGreeting"> Hello, there! </div>
和原生 hidden 属性不同, angular2 中的 *ngIf 不受样式约束。无论你写了什么样的CSS,她都是安全的。但还是有必要提一下, *ngIf 并不是控制元素的显示状态,而是直接通过从模版中增加/删除元素该元素来达成显示与否这一效果的。
当然你也可以通过全局的样式给元素的 hidden 属性增加隐藏的优先级,譬如: display: none !important ,来达到这个效果。你或许会问,既然 angular 小组都知道这些问题,那干嘛不在框架里直接给 hidden 加一个全局最高优先级的隐藏样式呢?答案是我们没法保证加全局样式对所有应用来说都是最佳选择。因为这种方式其实破坏了那些依赖原生 hidden 能力的功能,所以我们把选择权交给工程师。