欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于angular中的重要指令詳解($eval,$parse和$compile)

 更新時間:2016年10月21日 10:23:02   投稿:jingxian  
下面小編就為大家?guī)硪黄赼ngular中的重要指令詳解($eval,$parse和$compile)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

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

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

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

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

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

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

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

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

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

<body ng-controller="TestCtrl">
  {{test}}
</body>

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

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

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

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

好了,上下文的概念已經(jīng)講完了,其實挺容易理解的,基本上和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服務性價比最高的幾行代碼,

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

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

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

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

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

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

1.獲取當前的表達式user.name

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

3.在上下問對象中尋找表達式,最終獲得“angular“這個字符創(chuàng)

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

我們看第二個方法setter方法

setter(context, 'newValue');//實際上就是 $parse('user.name').assign(context, 'newValue')
expect(context.user.name).toEqual('newValue');//測試數(shù)據(jù)上下文的值是否被改變

這里的setter方法其實是改變值得方法

1.獲取當前的表達式user.name

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

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

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

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

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

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

1.獲取當前的表達式user.name

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

3.覆蓋當前的上下文{user:{name:'local'}}

4.獲取解析之后表達式的值

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

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

--------------------------------------------------

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

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

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

但是在指令中,她會返回兩個函數(shù)pre-link和post-link

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

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

以上就是小編為大家?guī)淼幕赼ngular中的重要指令詳解($eval,$parse和$compile)全部內(nèi)容了,希望大家多多支持腳本之家~

相關(guān)文章

  • AngularJS點擊添加樣式、點擊變色設置的實例代碼

    AngularJS點擊添加樣式、點擊變色設置的實例代碼

    本篇文章主要介紹了AngularJS點擊添加樣式、點擊變色設置的實例代碼,具有一定的參考價值,有興趣的可以了解一下
    2017-07-07
  • 淺談angularJS的$watch失效問題的解決方案

    淺談angularJS的$watch失效問題的解決方案

    本篇文章主要介紹了淺談angularJS的$watch失效問題的解決方案,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-08-08
  • Angular中$compile源碼分析

    Angular中$compile源碼分析

    本文給大家分享的是通過angular中的$compile源碼進行分析,從而更好的理解angular的使用,非常的不錯,希望大家能夠喜歡。
    2016-01-01
  • AngularJS 作用域詳解及示例代碼

    AngularJS 作用域詳解及示例代碼

    本文主要介紹AngularJS 作用域的知識,這里整理了基礎資料,和示例代碼以及實現(xiàn)效果圖,有需要的小伙伴可以參考下
    2016-08-08
  • AngularJS實現(xiàn)路由實例

    AngularJS實現(xiàn)路由實例

    本文給大家分享的是使用angularjs路由框架實現(xiàn)的一個簡單頁面跳轉(zhuǎn)功能,非常的實用,也很詳細,有需要的小伙伴可以參考下
    2017-02-02
  • angular2路由切換改變頁面title的示例代碼

    angular2路由切換改變頁面title的示例代碼

    本篇文章主要介紹了angular2路由切換改變頁面title的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • 詳解Angular6 熱加載配置方案

    詳解Angular6 熱加載配置方案

    這篇文章主要介紹了詳解Angular6 熱加載配置方案,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • AngularJS日期格式化常見操作實例分析

    AngularJS日期格式化常見操作實例分析

    這篇文章主要介紹了AngularJS日期格式化常見操作,結(jié)合實例形式分析了AngularJS日期格式化常用參數(shù)功能、設置與使用技巧,需要的朋友可以參考下
    2018-05-05
  • 微信小程序?qū)崿F(xiàn)左右聯(lián)動的實戰(zhàn)記錄

    微信小程序?qū)崿F(xiàn)左右聯(lián)動的實戰(zhàn)記錄

    聯(lián)動菜單是大家在開發(fā)小程序經(jīng)常會遇到的一個功能,下面這篇文章主要給大家介紹了關(guān)于微信小程序?qū)崿F(xiàn)左右聯(lián)動的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧
    2018-07-07
  • Angular 4.x 路由快速入門學習

    Angular 4.x 路由快速入門學習

    這篇文章主要介紹了Angular 4.x 路由快速入門學習,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05

最新評論