成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

angular1.x 中重要指令介紹($eval,$parse和$compile)

terasum / 2304人閱讀

摘要:實(shí)際上就是這里要表現(xiàn)的其實(shí)是上下文的替換功能。這就是死模板了,而所謂的活模板,就是這里面的數(shù)據(jù)全部經(jīng)過(guò)了數(shù)據(jù)的綁定會(huì)自動(dòng)找到當(dāng)前的上下文,來(lái)綁定數(shù)據(jù)。最后顯示出來(lái)的就是活模板,也就是經(jīng)過(guò)數(shù)據(jù)綁定的模板。

這篇文章是我兩年前在博客園寫(xiě)的,現(xiàn)在移植過(guò)來(lái),不過(guò)Angular 1.x 在國(guó)內(nèi)用的人已經(jīng)不多了,希望能幫助到有需要的人

在 angular 的服務(wù)中,有一些服務(wù)你不得不去了解,因?yàn)樗梢哉f(shuō)是 ng 的核心,而今天,我要介紹的就是 ng 的兩個(gè)核心服務(wù),$parse$compile 。其實(shí)這兩個(gè)服務(wù)講的人已經(jīng)很多了,但是 100 個(gè)讀者就有 100 個(gè)哈姆雷特,我在這里講講自己對(duì)于他們兩個(gè)服務(wù)的理解。

大家可能會(huì)疑問(wèn),$eval 呢,其實(shí)他并不是一個(gè)服務(wù),他是 scope 里面的一個(gè)方法,并不能算服務(wù),而且它也基于 parse 的,所以只能算是$parse 的另一種寫(xiě)法而已,我們看一下 ng 源碼中 $eval 的定義是怎樣的就知道了

$eval: function(expr, locals) {
  return $parse(expr)(this, locals);
}

相信看完源碼大家就明白了吧,好了,現(xiàn)在就開(kāi)始兩種核心服務(wù)的講解了,如果感覺(jué)我說(shuō)的不對(duì)的話,歡迎在評(píng)論區(qū)或者私聊指出,免得禍害其他讀者。

再講這兩個(gè)服務(wù)的時(shí)候,我要先講一個(gè)在本貼的概念:上下文

我相信,很多人都聽(tīng)過(guò)這個(gè)“上下文”,但是可能有點(diǎn)模糊,在我這里給大家解釋解釋看看大家接不接受這個(gè)說(shuō)法。

還記得 angular 的數(shù)據(jù)綁定嗎?比如:我現(xiàn)在有個(gè)有個(gè)叫 TestCtrl 的控制器,他的內(nèi)容如下:

.controller("TestCtrl", function($scope) {
  $scope.test = "Boo!!!"
})

而在 html 中我們的代碼是這樣的

  
    {{test}}
  

那么,大家不用想都知道結(jié)果了,頁(yè)面上肯定會(huì)顯示 Boo!!! 的字樣。

但是如果我刪掉 ng-controller 的指令呢?也就是我沒(méi)有在 html 申明控制器,你直接綁定{{test}}會(huì)如何呢?

結(jié)果只有一個(gè),那就是頁(yè)面啥都沒(méi)有(ps:因?yàn)槟闵昝髁?ng-app)。講到這里大家明白了嗎?

控制器就相當(dāng)于一個(gè)上下文的容器,真正的上下文其實(shí)是 $scope ,當(dāng)頁(yè)面綁定 test,如果申明了控制器,當(dāng)前上下文就是控制器里面的$scope ,ng 會(huì)去找一下你這個(gè)控制器的上下文$scope 有沒(méi)有 test,如果有,他當(dāng)然就顯示出來(lái)了,但是你不申明控制器的時(shí)候呢?他的上下文容器就是 ng-app 了,那么他真正的上下文就是 $rootScope ,這個(gè)時(shí)候他就會(huì)尋找 $rootScope 有沒(méi)有 test。

好了,上下文的概念已經(jīng)講完了,其實(shí)挺容易理解的,基本上和 this 非常相似

那么言歸正傳,我們開(kāi)始講 $parse,首先我們要看的是 ng 的 API 文檔

var getter = $parse("user.name");
var setter = getter.assign;
var context = {user:{name:"angular"}};
var locals = {user:{name:"local"}};

expect(getter(context)).toEqual("angular");
setter(context, "newValue");
expect(context.user.name).toEqual("newValue");
expect(getter(context, locals)).toEqual("local");

大家看到的是 ng 文檔里面對(duì)于$parse 服務(wù)性?xún)r(jià)比最高的幾行代碼,

gettersetter 就是大家所熟知的 get 方法和 set 方法了,contextlocals 僅僅是 json 對(duì)象而已,目的就是模擬上下文關(guān)系

大家看到的下面四個(gè)語(yǔ)句最終都能通過(guò)測(cè)試,現(xiàn)在我們一個(gè)個(gè)來(lái)分析,分析之前我要解釋一遍什么叫 $parse

$parse 服務(wù)其實(shí)就是一種解析表達(dá)式的功能,就像 ng-model=“test”,你在 html 中寫(xiě)這個(gè)東西誰(shuí)知道你 ng-model=“test”中,其實(shí)你想綁定的是當(dāng)前控制器(上下文容器)中 scope(上下文)中的 test 里面的值,ng 就是通過(guò)$parse 服務(wù)去幫助你解析這個(gè)表達(dá)式的,所以在調(diào)用$parse 服務(wù)的時(shí)候你需要傳遞上下文對(duì)象,讓 ng 知道你是要去哪里的 scope(上下文)去找你這個(gè) test。

所以我們看到第一行測(cè)試代碼是這樣的:

getter(context)).toEqual("angular") //實(shí)際上就是 $parse("user.name")(context)

在這個(gè) context 就是上下文,他能返回“angular“這個(gè)字符串的原理就是經(jīng)過(guò)這三步的:

獲取當(dāng)前的表達(dá)式 user.name

獲取當(dāng)前的上下文對(duì)象{user:{name:"angular"}}

在上下問(wèn)對(duì)象中尋找表達(dá)式,最終獲得“angular“這個(gè)字符創(chuàng)

所以這句測(cè)試代碼是成功的。

我們看第二個(gè)方法 setter 方法

setter(context, "newValue");  //實(shí)際上就是 $parse("user.name").assign(context, "newValue")
expect(context.user.name).toEqual("newValue");  //測(cè)試數(shù)據(jù)上下文的值是否被改變  這里的 setter 方法其實(shí)是改變值得方法

獲取當(dāng)前的表達(dá)式 user.name

獲取當(dāng)前的上下文對(duì)象{user:{name:"angular"}}

改變表達(dá)式中的值,將上下文對(duì)象編程{user:{name:"newValue"}}

于是上下文對(duì)象發(fā)生了改變,重新用 getter 方法去獲取表達(dá)式的時(shí)候,上下文已經(jīng)從 {user:{name:"angular"}} --> {user:{name:"newValue"}},最后獲取的表達(dá)式的值自然就是 newValue 了,所以測(cè)試代碼也是通過(guò)的。

expect(getter(context, locals)).toEqual("local");//實(shí)際上就是$parse("user.name")(context, locals)

這里要表現(xiàn)的其實(shí)是上下文的替換功能。

在 getter 的方法中我們不僅可以選擇第一個(gè)上下文,但是如果我們傳遞了第二個(gè)參數(shù),那么第一個(gè)上下文就會(huì)被第二個(gè)上下文覆蓋,注意是覆蓋.

獲取當(dāng)前的表達(dá)式 user.name

獲取當(dāng)前的上下文對(duì)象{user:{name:"angular"}}

覆蓋當(dāng)前的上下文{user:{name:"local"}}

獲取解析之后表達(dá)式的值

重新回到 $eval 這個(gè)地方,我們看待 $eval 源碼中可以看出$eval 只有 get 功能,而沒(méi)有 set 功能,但是有些時(shí)候我們可以選擇傳遞第二個(gè)上下文,來(lái)達(dá)到修改值得效果。

在這里 $parse 服務(wù)就已將說(shuō)完了,接下來(lái)就是 $compile

如果你了解了 $parse 的概念之后,我想 $compile 也差不多理解了,其實(shí)和 $parse 很像。但是他是解析一段 html 代碼的,他的功能就是將死模板變成活模板,也是指令的核心服務(wù)。

比如你有一段 html 代碼

{{test}}

,如果你將這段代碼直接放在 html 代碼里面,它所呈現(xiàn)的內(nèi)容是怎樣的我不說(shuō)大家也應(yīng)該懂。這就是死模板了,而所謂的活模板,就是這里面的數(shù)據(jù)全部經(jīng)過(guò)了數(shù)據(jù)的綁定 {{test}}會(huì)自動(dòng)找到當(dāng)前的上下文,來(lái)綁定數(shù)據(jù)。最后顯示出來(lái)的 就是活模板,也就是經(jīng)過(guò)數(shù)據(jù)綁定的模板。

$compile("死模板")(上下文對(duì)象),這樣就將死模板編程了活模板,你就可以對(duì)這段活的 html 代碼做操作了,例如增加到當(dāng)前節(jié)點(diǎn),等等。

但是在指令中,她會(huì)返回兩個(gè)函數(shù) pre-linkpost-link

第一個(gè)執(zhí)行的是 pre-link,它對(duì)于同一個(gè)指令的遍歷順序是從父節(jié)點(diǎn)到子節(jié)點(diǎn)的遍歷,在這個(gè)階段,dom 節(jié)點(diǎn)還沒(méi)有穩(wěn)定下來(lái),無(wú)法做一些綁定事件的操作,但是我們可以在這里進(jìn)行一些初始化數(shù)據(jù)的處理。

第二個(gè)執(zhí)行的是 post-link,也就是我們常說(shuō)的 link 函數(shù),他是從子節(jié)點(diǎn)到父節(jié)點(diǎn)遍歷的,在這個(gè)階段,DOM 節(jié)點(diǎn)已經(jīng)穩(wěn)定下來(lái)了,我們一般會(huì)在這里進(jìn)行很多的操作。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/92912.html

相關(guān)文章

  • 如何實(shí)現(xiàn)一個(gè)基于 DOM 的模板引擎

    摘要:我們提取變量的目的就是為了在函數(shù)中生成相應(yīng)的變量賦值的字符串便于在函數(shù)中使用,例如這樣的話,只需要在調(diào)用這個(gè)匿名函數(shù)的時(shí)候傳入對(duì)應(yīng)的即可獲得我們想要的結(jié)果了。 showImg(https://segmentfault.com/img/bVSspq?w=4000&h=2670); 題圖:Vincent Guth 注:本文所有代碼均可在本人的個(gè)人項(xiàng)目colon中找到,本文也同步到了知乎專(zhuān)欄...

    maxmin 評(píng)論0 收藏0
  • Angular1.x + TypeScript 編碼風(fēng)格

    摘要:組件還包含數(shù)據(jù)事件的輸入與輸出,生命周期鉤子和使用單向數(shù)據(jù)流以及從父組件上獲取數(shù)據(jù)的事件對(duì)象備份。 說(shuō)明:參照了Angular1.x+es2015的中文翻譯,并將個(gè)人覺(jué)得不合適、不正確的地方進(jìn)行了修改,歡迎批評(píng)指正。 架構(gòu),文件結(jié)構(gòu),組件,單向數(shù)據(jù)流以及最佳實(shí)踐 來(lái)自@toddmotto團(tuán)隊(duì)的實(shí)用編碼指南 Angular 的編碼風(fēng)格以及架構(gòu)已經(jīng)使用ES2015進(jìn)行重寫(xiě),這些在Angul...

    ytwman 評(píng)論0 收藏0
  • 使用 ES2015 開(kāi)發(fā) Angular1.x 應(yīng)用指南

    摘要:他們即不是指令,也不應(yīng)該使用組件代替指令,除非你正在用控制器升級(jí)模板指令,組件還包含數(shù)據(jù)事件的輸入與輸出,生命周期鉤子和使用單向數(shù)據(jù)流以及從父組件上獲取數(shù)據(jù)的事件對(duì)象。 showImg(https://segmentfault.com/img/bVynsJ); 關(guān)鍵詞 架構(gòu), 文件結(jié)構(gòu), 組件, 單向數(shù)據(jù)流以及最佳實(shí)踐 來(lái)自 @toddmotto 團(tuán)隊(duì)的編碼指南 Angular 的編碼...

    Andrman 評(píng)論0 收藏0
  • 關(guān)于Angularjs自定義指令一些有價(jià)值的細(xì)節(jié)技巧

    摘要:屬性為時(shí),指示優(yōu)先級(jí)小于當(dāng)前指令的指令都不執(zhí)行,僅執(zhí)行到本指令。 作者:心葉時(shí)間:2018-04-22 10:58 一:自定義指令常用模板 下面是大致的說(shuō)明,不是全面的,后面來(lái)具體說(shuō)明一些沒(méi)有提及的細(xì)節(jié)和重要的相關(guān)知識(shí): angular.module(yelloxingApp, []).directive(uiDirective, function() { return { ...

    Markxu 評(píng)論0 收藏0
  • 聊聊Vue.js的template編譯

    摘要:具體可以查看抽象語(yǔ)法樹(shù)。而則是帶緩存的編譯器,同時(shí)以及函數(shù)會(huì)被轉(zhuǎn)換成對(duì)象。會(huì)用正則等方式解析模板中的指令等數(shù)據(jù),形成語(yǔ)法樹(shù)。是將語(yǔ)法樹(shù)轉(zhuǎn)化成字符串的過(guò)程,得到結(jié)果是的字符串以及字符串。里面的節(jié)點(diǎn)與父節(jié)點(diǎn)的結(jié)構(gòu)類(lèi)似,層層往下形成一棵語(yǔ)法樹(shù)。 寫(xiě)在前面 因?yàn)閷?duì)Vue.js很感興趣,而且平時(shí)工作的技術(shù)棧也是Vue.js,這幾個(gè)月花了些時(shí)間研究學(xué)習(xí)了一下Vue.js源碼,并做了總結(jié)與輸出。 文...

    gnehc 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<