走進AngularJs(四)自訂指令----(中)

來源:互聯網
上載者:User

標籤:pre   模板   知識點   關聯   attr   重要   轉換   初始化   scope   

  上一篇簡單介紹了自訂一個指令的幾個簡單參數,restrict、template、templateUrl、replace、transclude,這幾個理解起來相對容易很多,因為它們只涉及到了表現,而沒有涉及行為。這一篇將繼續學習ng自訂指令的幾個重量級參數,瞭解了它們之後我們的custom directive將不光能“看”,還要能“動”。開始~

理解compile和link

  不知大家有沒有這樣的感覺,自己定義指令的時候跟寫jQuery外掛程式有幾分相似之處,都是先預先定義好頁面結構及監聽函數,然後在某個元素上調用一下,該元素便擁有了特殊的功能。區別在於,jQuery的側重點是DOM操作,而ng的指令中除了可以進行DOM操作外,更注重的是資料和模板的綁定。jQuery外掛程式在調用的時候才開始初始化,而ng指令在頁面載入進來的時候就被編譯服務($compile)初始化好了。

  在指令定義對象中,有compile和link兩個參數,它們是做什麼的呢?從字面意義上看,編譯、連結,貌似太抽象了點。其實可大有內涵,為了在自訂指令的時候能正確使用它們,現在有必要瞭解一下ng是如何編譯指令的。上一篇我有列了一下指令的執行流程,但僅僅列1234有點太對不起觀眾了,故在此詳細分析一下。此知識點相當重要。

指令的解析流程詳解

  我們知道ng架構會在頁面載入完畢的時候,根據ng-app劃定的範圍來調用$compile服務進行編譯,這個$compile就像一個大總管一樣,清點範圍內的DOM元素,看看哪些元素上使用了指令(如<div ng-modle=”m”></div>),或者哪些元素本身就是個指令(如<mydierc></mydirec>),或者使用了插值指令( {{}}也是一種指令,叫interpolation directive),$compile大總管會把清點好的財產做一個清單,然後根據這些指令的優先順序(priority)排列一下,真是個細心的大總管哈~大總管還會根據指令中的配置參數(template,place,transclude等)轉換DOM,讓指令“初具人形”。

  然後就開始按順序執行各指令的compile函數,注意此處的compile可不是大總管$compile,人家帶著$是土豪,此處執行的compile函數是我們指令中配置的,compile函數中可以訪問到DOM節點並進行操作,其主要職責就是進行DOM轉換,每個compile函數執行完後都會返回一個link函數,這些link函數會被大總管匯合一下組合成一個合體後的link函數,為了好理解,我們可以把它想象成葫蘆小金剛,就像是進行了這樣的處理


//合體後的link函數function AB(){  A(); //子link函數  B(); //子link函數}

  接下來進入link階段,合體後的link函數被執行。所謂的連結,就是把view和scope連結起來。連結成啥樣呢?就是我們熟悉的資料繫結,通過在DOM上註冊監聽器來動態修改scope中的資料,或者是使用$watchs監聽 scope中的變數來修改DOM,從而建立雙向繫結。由此也可以斷定,葫蘆小金剛可以訪問到scope和DOM節點。

  不要忘了我們在定義指令中還配置著一個link參數呢,這麼多link千萬別搞混了。那這個link函數是幹嘛的呢,我們不是有葫蘆小金剛了嘛?那我告訴你,其實它是一個小三。此話怎講?compile函數執行後返回link函數,但若沒有配置compile函數呢?葫蘆小金剛自然就不存在了。正房不在了,當然就輪到小三出馬了,大總管$compile就把這裡的link函數拿來執行。這就意味著,配置的link函數也可以訪問到scope以及DOM節點。值得注意的是,compile函數通常是不會被配置的,因為我們定義一個指令的時候,大部分情況不會通過編程的方式進行DOM操作,而更多的是進行監聽器的註冊、資料的綁定。所以,小三名正言順的被大總管寵愛~

  聽完了大總管、葫蘆小金剛和小三的故事,你是不是對指令的解析過程比較清晰了呢?不過細細推敲,你可能還是會覺得情節生硬,有些細節似乎還是沒有透徹的明白,所以還需要再理解下面的知識點:

compile和link的區別

  其實在我看完官方文檔後就一直有疑問,為什麼監聽器、資料繫結不能放在compile函數中,而偏偏要放在link函數中?為什麼有了compile還需要link?就跟你質疑我編的故事一樣,為什麼最後小三被寵愛了?所以我們有必要探究一下,compile和link之間到底有什麼區別。好,正房與小三的PK現在開始。

         首先是效能。舉個例子:


<ul>  <li ng-repeat="a in array">    <input ng-modle=”a.m” />  </li></ul>

         我們的觀察目標是ng-repeat指令。假設一個前提是不存在link。大總管$compile在編譯這段代碼時,會尋找到ng-repeat,然後執行它的compile函數,compile函數根據array的長度複製出n個<li>標籤。而複製出的<li>節點中還有<input>節點並且使用了ng-modle指令,所以compile還要掃描它並匹配指令,然後綁定監聽器。每次迴圈都做如此多的工作。而更加糟糕的一點是,我們會在程式中向array中添加元素,此時頁面上會即時更新DOM,每次有新元素進來,compile函數都把上面的步驟再走一遍,豈不是要累死了,這樣效能必然不行。

         現在扔掉那個假設,在編譯的時候compile就只管產生DOM的事,碰到需要綁定監聽器的地方先存著,有幾個存幾個,最後把它們匯總成一個link函數,然後一併執行。這樣就輕鬆多了,compile只需要執行一次,效能自然提升。

         另外一個區別是能力。儘管compile和link所做的事情差不多,但它們的能力範圍還是不一樣的。比如正房能管你的存款,小三就不能。小三能給你初戀的感覺,正房卻不能。

         我們需要看一下compile函數和link函數的定義:

function compile(tElement, tAttrs, transclude) { ... }function link(scope, iElement, iAttrs, controller) { ... }   

         這些參數都是通過依賴注入而得到的,可以按需聲明使用。從名字也容易看出,兩個函數各自的職責是什麼,compile可以拿到transclude,允許你自己編程管理乾坤大挪移的行為。而link中可以拿到scope和controller,可以與scope進行資料繫結,與其他指令進行通訊。兩者雖然都可以拿到element,但是還是有區別的,看到各自的首碼了吧?compile拿到的是編譯前的,是從template裡拿過來的,而link拿到的是編譯後的,已經與範圍建立了關聯,這也正是link中可以進行資料繫結的原因。

  正房與小三的區別就是效能和能力兩個關鍵字,簡記為效能力,我想你永遠都不會忘記了吧,真相就是如此的赤裸裸啊~哈哈

  我暫時只能理解到這個程度了。實在不想理解這些知識的話,只要簡單記住一個原則就行了:如果指令只進行DOM的修改,不進行資料繫結,那麼配置在compile函數中,如果指令要進行資料繫結,那麼配置在link函數中。

無奈的結束

  理解指令的處理流程以及compile和link的區別,花費了我大量的時間。資料太少了,官方文檔翻來覆去看,最後理解到了這個程度,但總覺得還是差那麼一點,沒有100%理解到位。今天太困了,就記錄到此處吧,以後有了新的理解再做補充。

  其實這篇的標題我想寫(下)的,直接把scope、require、controller一併介紹完畢,現在看來是不可能了,因為這幾個參數也是需要重點理解的,這樣下去篇幅又hold不住了。這裡就當是預報好了。。。囧。。。以前覺得沒有附圖和程式碼範例的部落格不是好部落格,現在反倒覺得要碼出這麼多字來,也是需要下功夫的。


來源:http://www.cnblogs.com/lvdabao/p/3398044.html



null

走進AngularJs(四)自訂指令----(中)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.