前幾天在用textangular富文本編輯器插件時,將存儲的文本及格式存儲到數據庫中,可是從後臺接口中再向angular頁面插入時卻不能執行,即在Angular中操做DOM沒有實現,後來查看了一下,操做DOM須要使用指令Directive封裝DOM,這樣嘗試以後終於解決了問題,從而對指令也有了很大的瞭解,之後再操做DOm就要當心了html
如下是我查閱資料時看到的,感受so詳細,解決了我不少issue,所以copy過來看看數據庫
原文http://www.cnblogs.com/xuema/p/4350747.htmlapp
指令也是一種服務,只是這種服務的定義有幾個特殊要求:編輯器
INSIDE:指令在注入器中的登記名稱是:指令名+Directive。 例如,ng-app指令的服務名稱是:"ngAppDirective"。函數
示例(http://www.dwz.cn/26R4S5中「使用指令封裝DOM操做」第一頁)定義一個簡單的指令ez-hoverable,這個指令被限制只能 出如今屬性的位置,每一個具備這個指令的HTML元素,將在鼠標移入 時以虛線邊框突出顯示。post
每一個指令定義的工廠函數,須要返回一個指令定義對象。指令定義對象就是 一個具備約定屬性的JavaScript對象,編譯器/$compile在編譯時就根據這 個定義對象對指令進行展開。spa
指令定義對象的經常使用屬性以下:插件
使用template指定的HTML標記替換指令內容(或指令自身)rest
用來限定指令在HTML模板中出現的位置。orm
使用這個屬性指明template的替換方式。
scope屬性爲指令建立私有的做用域,這在建立可複用的Widget時很是有用。
link屬性是一個函數,用來在指令中操做DOM樹、實現數據綁定。
容許指令包含其餘HTML元素,這一般用於實現一個容器類型的Widget。
最簡單的指令只須要使用template屬性進行模板替換就能夠實現。
template指明一個HTML片斷,能夠用來:
示例(http://www.dwz.cn/26R4S5中「使用指令封裝DOM操做」第三頁)實現了一個ezCustomer指令,這個指令只是簡單的使用template指定的 模板替換ez-customer的內容:
restict屬性能夠是EACM這四個字母的任意組合,用來限定指令的應用場景。 若是不指定這個屬性,默認狀況下,指令將僅容許被用做元素名和屬性名:
咱們對以前的示例,增長一個restrict屬性,限制這個只能做爲元素名使用。 代碼已經預置到右邊,你能夠看到,如今惟一合法的方式是使用以下方式應用指令:
考查編譯後的DOM結構,你會發現ez-customer這個」僞「HTML標籤還被保留着,這有時讓完美 主義者有點鬧心:
咱們但願使用template完整地替換原始的DOM對象,而不是填充其內容,replace 屬性負責這件事。
replace屬性指明使用template時,如何替換指令元素:
示例(http://www.dwz.cn/26R4S5中「使用指令封裝DOM操做」第五頁)增長了replace屬性,值爲true意味着這個指令要求編譯器使用template 替換原始的DOM元素:
你可能注意到模板的內容稍微修改了一下,這是由於replace爲true時,要求模板有 一個根節點。
默認狀況下,指令沒有本身的scope對象,換句話說,它使用所在DOM對象對應的scope對象。
那麼問題來了,若是一個指令在同一個scope內出現屢次,會怎樣?
沒錯,因爲兩個ez-customer指令都處在ezCtrl開闢的做用域內,因此兩個指令綁定到了一樣的 數據模型上,獲得的是重複的結果。
顯然,咱們能夠將每一個ez-customer指令置於不一樣的做用域下,這意味着咱們給每一個ez-customer 一個不一樣的控制器:
看起來很怪異,對嗎?
經過設置scope屬性,指令的每一個實例都將得到一個隔離的本地做用域:
在上面的例子中,咱們在本地scope上定義了兩個屬性:name和address,這樣在 模板中就可使用name和address了。
你應該已經注意到,name屬性的值以前有一個@符號,這是一個約定好的標記,它 告訴編譯器,本地scope上的name值須要從應用這個指令的DOM元素的name屬性值 讀取,若是DOM元素的name屬性值變了,那麼本地scope上的name值也會變化。
一樣,address屬性以前的=符號也是一個約定好的標記,它告訴編譯器,本地scope 上的address屬性值和DOM元素的address屬性值指定的外部scope對象上的模型須要 創建雙向鏈接:外部scope上模型的變化會改變本地scope上的address屬性,本地 scope上address屬性的變化也會改變外部scope上模型的變化。
有點繞,上個圖:
從圖中能夠看出:
若是須要在指令中操做DOM,咱們須要在對象中定義link屬性,link函數的定義以下:
注意link函數的參數,AngularJS在編譯時負責傳入正確的值:
指令對應的scope對象。若是指令沒有定義本身的本地做用域,那麼傳入的就是外部的 做用域對象。
指令所在DOM對象的jqLite封裝。若是使用了template屬性,那麼iElement對應 變換後的DOM對象的jqLite封裝。
指令所在DOM對象的屬性集。這是一個Hash對象,每一個鍵是駝峯規範化後 的屬性名。
後兩個參數咱們先略過。
示例(http://www.dwz.cn/26R4S5中「使用指令封裝DOM操做」第八頁)中,咱們實現了一個能夠指定顯示格式的小時鐘指令:ezCurrentTime。和原來同樣, 咱們在link函數中啓動定時器,並在定時器中更新DOM。有幾點解釋下:
有些指令須要可以包含其餘未知的元素。好比咱們定義一個指令ez-dialog,用來 封裝對話框的樣式和行爲,它應當容許在使用期(也就是在界面模板文件裏)才指 定其內容:
transclude屬性能夠告訴編譯器,利用所在DOM元素的內容,替換template中包含 ng-transclude指令的元素的內容:
從上圖中能夠看到,使用transclude有兩個要點:
右邊嵌入了ez-dialog的實現實例(http://www.dwz.cn/26R4S5中「使用指令封裝DOM操做」第九頁)。