在使用Anguarjs進行web開發或者進行SPA(single page application)開發時,每每會遇到下面這樣的問題。css
刷新頁面時,頁面會出現一些亂碼,這裏的亂碼具體是指`{{expression}}`或者`{{expression | filter}}`這種形式的表達式亂碼,而後這些亂碼又快速的消失了,而後頁面就正常了。這個問題的緣由是,在一些現代瀏覽器,好比Chrome,Firefox等中尤其嚴重。固然還跟環境的網絡速度有關。html
出現這個問題的根本緣由是,JavaScript操做DOM都是在DOM加載完成(DOM Ready)以後的才進行的。換句話說,Angularjs只會在DOM Ready以後纔回去解析html模版以及Angularjs的directive,在這以前html模版中的內容會被原封不動的展現在頁面,這時候就會出現所謂的亂碼問題。web
那麼咱們如何解決這個問題呢?express
Angularjs官方針對這個問題提供了原生的解決方案,就是咱們今天要說的主角 ng-cloak
指令。瀏覽器
咱們先來看一下Angularjs的源碼中對這個 ng-cloak
是如何實現的。網絡
Angularjs將 ng-cloak
實現爲directive,其代碼以下,app
!angular.$$csp() && angular .element(document) .find('head') .prepend('<style type="text/css">' + '@charset "UTF-8";' + '[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}' + 'ng\\:form{display:block;}' + '.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}' + </style>');
你們不要對這一坨代碼感到畏懼,其實它作的事很簡單,就是在html的中 head
標籤中插入一段內聯的css樣式。其中部分的代碼是這樣的,ide
[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak, .ng-hide { display:none !important; }
很顯然,Angularjs對 ng-cloak
相關的元素設置了 display: none !important
這樣一個屬性,目的就是隱藏相關元素。這樣在在DOM尚未Ready的時候,將相關元素隱藏起來,這樣頁面就不會出現亂碼了。spa
當DOM Ready的時候,Angularjs開始解析指令。咱們來看一下 ng-cloak
這個指令都作了哪些事情,code
var ngCloakDirective = ngDirective({ compile: function(element, attr) { attr.$set('ngCloak', undefined); element.removeClass('ng-cloak'); } });
可見,當Angularjs開始解析 ng-cloak
指令的時候,又會把這個樣式給去除掉。這樣頁面又顯示了。
經過以上分析,咱們知道了使用 ng-cloak
指令來避免頁面出現亂碼的原理,其實經過先隱藏後顯示來規避了DOM還沒有Ready這段時間的真空期。
在實際使用的過程當中,咱們要想使上面的過程完美表現,就必需要先在 head
標籤中先引入Angularjs的源碼,而不能在頁面的最後引入Angularjs文件。
由於後者會形成這樣一種狀況:在Angularjs文件還沒引入時,意味着還沒給 ng-cloak
相關元素作隱藏處理,頁面就已經展現了,這是頁面仍然會出現亂碼。
可是通常性的原則告訴咱們, 應該把css文件放在頭部,把js文件放在尾部 。那麼咱們如何解決這個矛盾呢?
解決方案是,咱們手動在 head
中將 ng-cloak
相關的元素設置爲隱藏,即添加以下的代碼,
<head> <style> [ng:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display:none !important; } </style> </head>
或者將這一段代碼放在咱們在 head
中加載的css文件中,這樣就能夠確保頁面加載的時候,無論它有沒有DOM Ready, ng-cloak
相關元素確定是隱藏的。
若是你發如今 body
上加了 ng-cloak
,可是仍然不起做用,那麼緣由應該就是上面所描述的,這時候你就須要在 head
中添加隱藏代碼或者在引入的css文件中添加相關代碼了。
最後提一點,若是 中的表達式僅僅是展現一些文本內容,咱們能夠使用
ng-bind
這個指令來實現。