在angular中,指令是乙個重要的概念,它作用在特定的dom元素上,可以擴充套件這個元素的功能,為元素增加新的行為。本質上,元件可以被理解為一種帶有檢視的指令。元件繼承自指令,是指令的乙個子類,通常被用來構造ui控制項。
指令的使用並不複雜,它與html元素屬性的使用方式相似。不同的是,html語法標準為html元素預定義了特定的屬性,瀏覽器遵循這一語法標準,實現了這些屬性的內建行為。語法標準預定義的屬性是有限的、不可擴充套件的,而angular中的指令是可自定義的、可任意擴充套件的,這在一定程度上彌補了標準html元素屬性功能的不足。
在angular中指令分為三類:屬性型指令,結構型指令和元件。
顧名思義,屬性指令是以元素屬性的形式來使用的指令。與html元素的內建屬性不同,指令是angular對html元素屬性的擴充套件,瀏覽器本身不能識別這些指令,指令僅在angular環境中才能被識別使用。屬性指令通常被用來改變元素的外觀和行為,如在第7章中介紹過的angular內建指令ngstyle,它可以基於元件的狀態來動態設定目標元素的樣式。
結構指令可以用來改變dom樹的結構。結構指令可以根據模板表示式的值,增加或刪除dom元素,從而改變dom的布局。結構指令與屬性指令的使用方式相同,都是以元素屬性的形式來使用的。兩者的區別在於使用場景不同,屬性指令用來改變元素的外觀和行為,而結構指令用來改變dom樹的結構。
以angular內建的結構指令ngif為例,使用ngif指令需要為指令繫結乙個表示式,當表示式值為true時,該dom元素及其子元素被新增至dom中;當表示式值為false時,元素從dom中被移除。示例**如下:
上面的**當condition的值為true時會顯示p元素,反之p元素會從dom中移除。
元件繼承自指令,它的**結構與指令也是相似的,不同之處在於元件有乙個自描述的模板,並且元件是用@component來修飾,而指令需要乙個宿主元素,用@directive來描述。
元件與指令的部分生命週期鉤子函式相同:
儘管元件與指令有相似的結構和一些相同的生命週期鉤子方法,但是它們也有一些不同點。不同於屬性指令和結構指令,元件不是以html元素屬性的形式使用的,而是以自定義標籤的形式使用的,原因在於元件帶有模板。元件可作為對html元素的擴充套件,將自身的模板檢視插入dom中;而屬性指令和結構指令是對html元素屬性的擴充套件,其作用是擴充套件已有dom元素的行為和樣式,或者改變這些元素在dom中的結構。
乙個屬性指令需要乙個控制器類,該控制器類使用@directive裝飾器來裝飾。@directive裝飾器指定了用以標記指令所關聯屬性的選擇器,控制器類則實現了指令所對應的特定行為。
首先需要從@angular/core中引入directive和elementref。前者包含了修飾指令的裝飾器@directive,後者通過指令的建構函式傳入,代表指令修飾的dom元素宿主。
@directive()angular會為每乙個匹配的dom元素建立乙個指令例項,同時將elementref作為引數注入到控制器建構函式。使用elementref服務,可以在**中通過其nativeelement屬性直接訪問dom元素,這樣就可以通過dom api設定元素的背景色:export
class
firstdirective implements oninit
ngoninit():
void
}
@directive()在上述的**中指令為宿主設定的顏色是固定的,如果要想動態的變更顏色,有兩個思路:export
class
firstdirective implements oninit
ngoninit():
void
}
第一,設定乙個@input輸入屬性,並將這個屬性定義為set函式:
@directive()第二,指令實現onchanges介面,在介面中處理邏輯:export
class
firstdirective
} constructor(
private
el: elementref)
}
@directive()然後在宿主中使用這個指令:export
class
firstdirective implements onchanges
constructor(
private
el: elementref)
}
color
" matline>template
在宿主中需要定義乙個color變數並且改變這個color變數的值,這裡就不演示了。
可以使用@hostlistener來響應使用者發出的事件。@hostlistener指向使用指令的dom元素,使得dom元素的事件與指令關聯起來。@hostlistener是另一種動態設定的方案,相比較前面那種@input set輸入屬性的方式還有生命週期鉤子的方式,這種方式是從響應使用者發出的事件的角度執行的。
//不同於屬性型指令,屬性型指令會在建構函式中傳入乙個elementref來表示它的宿主dom元素,而結構型指令需要在構造器中傳入兩個引數,乙個是templeteref,另乙個是viewcontainerref.這是因為被結構型指令修飾的dom元素會被angular轉譯成乙個元素:.....其他**....
@hostlistener('
click')
onclick()
"上面的**會被angular轉譯為:condition
">can you see it?
"可以看出結構型指令會被轉譯成乙個屬性型的指令。condition
">
can you see it?
所以,結構型指令需要傳入乙個temeplateref的服務來訪問到這個元件模板(被轉譯成的ng-template)。至於另乙個viewcontainerref,這個服務是可以從dom中建立或者刪除乙個templateref所代表的模板元素,要取決於對結構型指令求值的boolean值(因為給結構型指令繫結的表示式必須是乙個boolean型別的表示式)。
下面**簡單定義了乙個結構型的指令:
@directive()看起來和屬性型的指令差不多,不同之處在於建構函式傳入的引數型別不同。使用上也和屬性型指令差不多,需要注意的就是viewcontainerref的兩個方法,這兩個方法都是用來操作指令中的templateref所指向的模板的:export
class
firstdirective
@input() condition: boolean;
}
createembeddedview():需要傳入乙個templateref型別的引數,表示根據templateref建立乙個內嵌的檢視模板。
clear():將templateref檢視模板中刪除。
angular學習筆記(6) 指令
angular1學習筆記 6 指令 restrict 匹配模式 1.a 屬性 2.m 注釋 3.e 元素 4.c 樣式類 注釋留空兩邊 推薦使用元素和屬性的方式使用指令 當需要建立帶有自己的模板的指令時,使用元素名稱的方式建立指令 當需要為已有的html標籤增加功能時,使用屬性的方式建立指令 sco...
Angular2 指令 路由指令
routeroutlet的作用是在模板中開闢出一片區域,用於顯示url所對應的元件,angular將模板中使用了 標籤的元件統稱為路由元件 router outlet main routerlink接收乙個連線引數陣列,angular將根據該陣列來生成urltree例項進行跳轉。routerlink...
angular學習筆記 三十 指令 1 概述
之前在 angular學習筆記 十九 指令修改dom 裡面已經簡單的提到了angular中的指令,現在來詳細的介紹 指令 一.指令的建立 require string link function scope,element,attrs,ctrl,transclude compile function...