在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
能力的功能,所以我们把选择权交给工程师。