国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

terasum / 2293人閱讀

摘要:實際上就是這里要表現的其實是上下文的替換功能。這就是死模板了,而所謂的活模板,就是這里面的數據全部經過了數據的綁定會自動找到當前的上下文,來綁定數據。最后顯示出來的就是活模板,也就是經過數據綁定的模板。

這篇文章是我兩年前在博客園寫的,現在移植過來,不過Angular 1.x 在國內用的人已經不多了,希望能幫助到有需要的人

在 angular 的服務中,有一些服務你不得不去了解,因為他可以說是 ng 的核心,而今天,我要介紹的就是 ng 的兩個核心服務,$parse$compile 。其實這兩個服務講的人已經很多了,但是 100 個讀者就有 100 個哈姆雷特,我在這里講講自己對于他們兩個服務的理解。

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

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

相信看完源碼大家就明白了吧,好了,現在就開始兩種核心服務的講解了,如果感覺我說的不對的話,歡迎在評論區或者私聊指出,免得禍害其他讀者。

再講這兩個服務的時候,我要先講一個在本貼的概念:上下文

我相信,很多人都聽過這個“上下文”,但是可能有點模糊,在我這里給大家解釋解釋看看大家接不接受這個說法。

還記得 angular 的數據綁定嗎?比如:我現在有個有個叫 TestCtrl 的控制器,他的內容如下:

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

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

  
    {{test}}
  

那么,大家不用想都知道結果了,頁面上肯定會顯示 Boo!!! 的字樣。

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

結果只有一個,那就是頁面啥都沒有(ps:因為你申明了 ng-app)。講到這里大家明白了嗎?

控制器就相當于一個上下文的容器,真正的上下文其實是 $scope ,當頁面綁定 test,如果申明了控制器,當前上下文就是控制器里面的$scope ,ng 會去找一下你這個控制器的上下文$scope 有沒有 test,如果有,他當然就顯示出來了,但是你不申明控制器的時候呢?他的上下文容器就是 ng-app 了,那么他真正的上下文就是 $rootScope ,這個時候他就會尋找 $rootScope 有沒有 test。

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

那么言歸正傳,我們開始講 $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 文檔里面對于$parse 服務性價比最高的幾行代碼,

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

大家看到的下面四個語句最終都能通過測試,現在我們一個個來分析,分析之前我要解釋一遍什么叫 $parse

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

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

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

在這個 context 就是上下文,他能返回“angular“這個字符串的原理就是經過這三步的:

獲取當前的表達式 user.name

獲取當前的上下文對象{user:{name:"angular"}}

在上下問對象中尋找表達式,最終獲得“angular“這個字符創

所以這句測試代碼是成功的。

我們看第二個方法 setter 方法

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

獲取當前的表達式 user.name

獲取當前的上下文對象{user:{name:"angular"}}

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

于是上下文對象發生了改變,重新用 getter 方法去獲取表達式的時候,上下文已經從 {user:{name:"angular"}} --> {user:{name:"newValue"}},最后獲取的表達式的值自然就是 newValue 了,所以測試代碼也是通過的。

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

這里要表現的其實是上下文的替換功能。

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

獲取當前的表達式 user.name

獲取當前的上下文對象{user:{name:"angular"}}

覆蓋當前的上下文{user:{name:"local"}}

獲取解析之后表達式的值

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

在這里 $parse 服務就已將說完了,接下來就是 $compile

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

比如你有一段 html 代碼

{{test}}

,如果你將這段代碼直接放在 html 代碼里面,它所呈現的內容是怎樣的我不說大家也應該懂。這就是死模板了,而所謂的活模板,就是這里面的數據全部經過了數據的綁定 {{test}}會自動找到當前的上下文,來綁定數據。最后顯示出來的 就是活模板,也就是經過數據綁定的模板。

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

但是在指令中,她會返回兩個函數 pre-linkpost-link

第一個執行的是 pre-link,它對于同一個指令的遍歷順序是從父節點到子節點的遍歷,在這個階段,dom 節點還沒有穩定下來,無法做一些綁定事件的操作,但是我們可以在這里進行一些初始化數據的處理。

第二個執行的是 post-link,也就是我們常說的 link 函數,他是從子節點到父節點遍歷的,在這個階段,DOM 節點已經穩定下來了,我們一般會在這里進行很多的操作。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92912.html

相關文章

  • 如何實現一個基于 DOM 的模板引擎

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

    maxmin 評論0 收藏0
  • Angular1.x + TypeScript 編碼風格

    摘要:組件還包含數據事件的輸入與輸出,生命周期鉤子和使用單向數據流以及從父組件上獲取數據的事件對象備份。 說明:參照了Angular1.x+es2015的中文翻譯,并將個人覺得不合適、不正確的地方進行了修改,歡迎批評指正。 架構,文件結構,組件,單向數據流以及最佳實踐 來自@toddmotto團隊的實用編碼指南 Angular 的編碼風格以及架構已經使用ES2015進行重寫,這些在Angul...

    ytwman 評論0 收藏0
  • 使用 ES2015 開發 Angular1.x 應用指南

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

    Andrman 評論0 收藏0
  • 關于Angularjs自定義指令一些有價值的細節技巧

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

    Markxu 評論0 收藏0
  • 聊聊Vue.js的template編譯

    摘要:具體可以查看抽象語法樹。而則是帶緩存的編譯器,同時以及函數會被轉換成對象。會用正則等方式解析模板中的指令等數據,形成語法樹。是將語法樹轉化成字符串的過程,得到結果是的字符串以及字符串。里面的節點與父節點的結構類似,層層往下形成一棵語法樹。 寫在前面 因為對Vue.js很感興趣,而且平時工作的技術棧也是Vue.js,這幾個月花了些時間研究學習了一下Vue.js源碼,并做了總結與輸出。 文...

    gnehc 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<