在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
能力的功能,所以我們把選擇權交給工程師。