使用Angularjs的ng

2018-06-07 18:43 更新

在使用Anguarjs進(jìn)行web開(kāi)發(fā)或者進(jìn)行SPA(single page application)開(kāi)發(fā)時(shí),往往會(huì)遇到下面這樣的問(wèn)題。

刷新頁(yè)面時(shí),頁(yè)面會(huì)出現(xiàn)一些亂碼,這里的亂碼具體是指`{{expression}}`或者`{{expression | filter}}`這種形式的表達(dá)式亂碼,然后這些亂碼又快速的消失了,然后頁(yè)面就正常了。這個(gè)問(wèn)題的原因是,在一些現(xiàn)代瀏覽器,比如Chrome,F(xiàn)irefox等中尤為嚴(yán)重。當(dāng)然還跟環(huán)境的網(wǎng)絡(luò)速度有關(guān)。

出現(xiàn)這個(gè)問(wèn)題的根本原因是,JavaScript操作DOM都是在DOM加載完成(DOM Ready)之后的才進(jìn)行的。換句話說(shuō),Angularjs只會(huì)在DOM Ready之后才回去解析html模版以及Angularjs的directive,在這之前html模版中的內(nèi)容會(huì)被原封不動(dòng)的展示在頁(yè)面,這時(shí)候就會(huì)出現(xiàn)所謂的亂碼問(wèn)題。

那么我們?nèi)绾谓鉀Q這個(gè)問(wèn)題呢?

Angularjs官方針對(duì)這個(gè)問(wèn)題提供了原生的解決方案,就是我們今天要說(shuō)的主角ng-cloak指令。

我們先來(lái)看一下Angularjs的源碼中對(duì)這個(gè)ng-cloak是如何實(shí)現(xiàn)的。

Angularjs將ng-cloak實(shí)現(xiàn)為directive,其代碼如下,


!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>');

大家不要對(duì)這一坨代碼感到畏懼,其實(shí)它做的事很簡(jiǎn)單,就是在html的中head標(biāo)簽中插入一段內(nèi)聯(lián)的css樣式。其中部分的代碼是這樣的,


[ng\\:cloak],
[ng-cloak],
[data-ng-cloak],
[x-ng-cloak],
.ng-cloak,
.x-ng-cloak,
.ng-hide {
    display:none !important;
}

很顯然,Angularjs對(duì)ng-cloak相關(guān)的元素設(shè)置了display: none !important這樣一個(gè)屬性,目的就是隱藏相關(guān)元素。這樣在在DOM還沒(méi)有Ready的時(shí)候,將相關(guān)元素隱藏起來(lái),這樣頁(yè)面就不會(huì)出現(xiàn)亂碼了。

當(dāng)DOM Ready的時(shí)候,Angularjs開(kāi)始解析指令。我們來(lái)看一下ng-cloak這個(gè)指令都做了哪些事情,


var ngCloakDirective = ngDirective({
    compile: function(element, attr) {
        attr.$set('ngCloak', undefined);
        element.removeClass('ng-cloak');
    }
});

可見(jiàn),當(dāng)Angularjs開(kāi)始解析ng-cloak指令的時(shí)候,又會(huì)把這個(gè)樣式給去除掉。這樣頁(yè)面又顯示了。

通過(guò)以上分析,我們知道了使用ng-cloak指令來(lái)避免頁(yè)面出現(xiàn)亂碼的原理,其實(shí)通過(guò)先隱藏后顯示來(lái)規(guī)避了DOM尚未Ready這段時(shí)間的真空期。

理論是美好的,但是現(xiàn)實(shí)往往會(huì)給我一個(gè)響亮的耳光。

在實(shí)際使用的過(guò)程中,我們要想使上面的過(guò)程完美表現(xiàn),就必須要先在head標(biāo)簽中先引入Angularjs的源碼,而不能在頁(yè)面的最后引入Angularjs文件。

因?yàn)楹笳邥?huì)造成這樣一種情況:在Angularjs文件還沒(méi)引入時(shí),意味著還沒(méi)給ng-cloak相關(guān)元素做隱藏處理,頁(yè)面就已經(jīng)展示了,這是頁(yè)面仍然會(huì)出現(xiàn)亂碼。

但是一般性的原則告訴我們,應(yīng)該把css文件放在頭部,把js文件放在尾部。那么我們?nèi)绾谓鉀Q這個(gè)矛盾呢?

解決方案是,我們手動(dòng)在head中將ng-cloak相關(guān)的元素設(shè)置為隱藏,即添加如下的代碼,


<head>
    <style>
        [ng:cloak],
        [ng-cloak],
        [data-ng-cloak],
        [x-ng-cloak],
        .ng-cloak,
        .x-ng-cloak {
            display:none !important;
        }
    </style>
</head>

或者將這一段代碼放在我們?cè)?code>head中加載的css文件中,這樣就可以確保頁(yè)面加載的時(shí)候,不管它有沒(méi)有DOM Ready,ng-cloak相關(guān)元素肯定是隱藏的。

如果你發(fā)現(xiàn)在body上加了ng-cloak,但是仍然不起作用,那么原因應(yīng)該就是上面所描述的,這時(shí)候你就需要在head中添加隱藏代碼或者在引入的css文件中添加相關(guān)代碼了。

最后提一點(diǎn),如果中的表達(dá)式僅僅是展示一些文本內(nèi)容,我們可以使用ng-bind這個(gè)指令來(lái)實(shí)現(xiàn)。



以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)