天天看點

angular4 結構型指令 屬性型指令總結

屬性型指令總結             看了幾次官網的屬性指令文檔,對一些關鍵的東西還是很混淆,學到的都是基于表面的使用,這裡是我把一些重要的東西給總結起來,友善自己看:

           1.三種指令:元件 、結構型指令(ngif  ngfor等)和屬性型指令 (所有元件都為指令)            結構型指令 —   通過添加和移除 DOM 元素改變 DOM 布局的指令

           屬性型指令 —   改變元素、元件或其它指令的外觀和行為的指令。

           2.angular在标簽元素上發現我們自定義的屬性,先考慮是否為指令,如果為就執行個體化這個指令類,這就意味着我們在模闆中引入這個指令,不用像服務一樣在構造函數裡聲明了,按我了解 元件 指令 管道 是處于同一等級的,這樣就不存在誰引入誰,直接拿來用就是了。

         3.使用資料綁定向指令傳遞值        使用@input 向指令傳遞值,            <p appHightlight highlightColor="yellow">Highlighted in yellow</p>

           <p appHightlight [highlightColor]="'orange'">Highlighted in orange</p>         注意這二者的差別@input向指令輸入值的方式不同,多了個[ ]時orange也多了個‘ ’,因為不加orange會當成一個類的屬性                  4.綁定到第二個屬性           可以直接寫在宿主裡 <p [ appHighlight ] = "color" defaultColor = "violet" > 不過也需要通過@input來接值                   5.這個是要注意的為什麼要加@Input?

           @Input裝飾器都告訴Angular,該屬性是公共的,并且能被父元件綁定。 如果沒有@Input,Angular就會拒絕綁定到該屬性。

但我們以前也曾經把模闆HTML綁定到元件的屬性,而且從來沒有用過@Input。 差異何在?

差異在于信任度不同。 Angular把元件的模闆看做從屬于該元件的。 元件和它的模闆預設會互相信任。 這也就是意味着,元件自己的模闆可以綁定到元件的任意屬性,無論是否使用了@Input裝飾器。

但元件或指令不應該盲目的信任其它元件或指令。 是以元件或指令的屬性預設是不能被綁定的。 從Angular綁定機制的角度來看,它們是私有的,而當添加了@Input時,它們變成了公共的 隻有這樣,它們才能被其它元件或屬性綁定。

你可以根據屬性名在綁定中出現的位置來判定是否要加@Input。

當它出現在等号右側的模闆表達式中時,它屬于模闆所在的元件,不需要@Input裝飾器。(資料源)

當它出現在等号左邊的方括号([ ])中時,該屬性屬于其它元件或指令,它必須帶有@Input 裝飾器。(因為angular操作的是dom的property 不是attribute 對不存在的dom屬性就不信任,是以有的不需要@input)

試用此原理分析下列範例:

src/app/app.component.html (color)

 content_copy

<p [appHighlight]="color">Highlight me!</p>

color屬性位于右側的綁定表達式中,它屬于模闆所在的元件。 該模闆群組件互相信任。是以color不需要@Input裝飾器。

myHighlight屬性位于左側,它引用了MyHighlightDirective中一個帶别名的屬性,它不是模闆所屬元件的一部分,是以存在信任問題。 是以,該屬性必須帶@Input裝飾器。

   二 結構型指令     結構型指令的職責是HTML布局。 它們塑造或重塑DOM的結構,比如添加、移除或維護這些元素。Angular會解開這個*文法糖,變成一個<ng-template>标記,包裹着宿主元素及其子元素

    1.NgIf 大駝峰為類,小駝峰為它的屬性。 當我們隐藏掉一個元素時,元件的行為還在繼續 —— 它仍然附加在它所屬的DOM元素上, 它也仍在監聽事件。Angular會繼續檢查哪些能影響資料綁定的變更。 元件原本要做的那些事情仍在繼續。

雖然不可見,元件及其各級子元件仍然占用着資源,而這些資源如果配置設定給别人可能會更有用。 在性能和記憶體方面的負擔相當可觀,響應度會降低,當然,從積極的一面看,重新顯示這個元素會非常快。 元件以前的狀态被保留着,并随時可以顯示。 元件不用重新初始化 —— 該操作可能會比較昂貴。 這時候隐藏和顯示就成了正确的選擇。

但是,除非有非常強烈的理由來保留它們,否則我們更傾向于移除使用者看不見的那些DOM元素,并且使用NgIf這樣的結構型指令來收回用不到的資源。                  *ngIf指令被移到了<ng-template>元素上。在那裡它變成了一個屬性綁定[ngIf]。

        <div>上的其餘部分,包括它的class屬性在内,移到了内部的<ng-template>元素上。(隻會顯示最終的結果)      2、ngfor          <div *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackById" [class.odd]="odd"> ({{i}}) {{hero.name}}</div>(三種用法)

    <ng-template ngFor let-hero [ngForOf]="heroes" let-i="index" let-odd="odd" [ngForTrackBy]="trackById"><div [class.odd]="odd">({{i}}) {{hero.name}}</div></ng-template>     3.ngswitch 為屬性型指令  ngswitchcase 為結構型指令

 三 自定義結構型指令 ng-template     優先使用星号(*)文法

 星号(*)文法比不帶文法糖的形式更加清晰。 如果找不到單一的元素來應用該指令,可以使用<ng-container>作為該指令的容器。

 雖然很少有理由在模闆中使用結構型指令的屬性形式和元素形式,但這些幕後知識仍然是很重要的,即:Angular會建立<ng-template>,還要了解它的工作原理。 當需要寫自 己的結構型指令時,我們就要使用<ng-template>, <ng-template>是一個 Angular 元素,用來渲染HTML。 它永遠不會直接顯示出來。 事實上,在渲染視圖之前,Angular 會把<ng-template>及其内容替換為一個注釋。自己寫一些标簽在ng-template時,不顯示當成注釋

    四、<ng-container> 的救贖 另一個問題是:有些HTML元素需要所有的直屬下級都具有特定的類型。 比如,<select>元素要求直屬下級必須為<option>,那麼我們就沒辦法把這些選項包裝進<div>或<span>中。  <span *ngFor="let h of heroes">

      <span *ngIf="showSad || h.emotion !== 'sad'">

      <option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>

      </span>option為空結構指令的錯亂

      Angular的<ng-container>是一個分組元素,但它不會污染樣式或元素布局,因為 Angular 壓根不會把它放進 DOM 中。       <ng-container *ngIf="hero">

    <option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>

     </ng-container>解決一些标簽不顯示的問題 (select option)

         雜項:       1. ElementRef是一個服務,它賦予我們通過它的nativeElement屬性直接通路 DOM 元素的能力。 Renderer服務允許通過代碼設定元素的樣式       [email protected]裝飾器引用屬性型指令的宿主元素 相當于addEventListene            當然,你可以通過标準的JavaScript方式手動給宿主 DOM 元素附加一個事件監聽器。 但這種方法至少有三個問題:            必須正确的書寫事件監聽器。當指令被銷毀的時候,            必須拆卸事件監聽器,否則會導緻記憶體洩露。             必須直接和 DOM API 打交道,應該避免這樣做。     [email protected]取别名@Input('appHighlight') highlightColor: string;     4. 每個宿主元素上隻能有一個結構型指令,  有一個簡單的解決方案:把*ngIf放在一個"容器"元素上,再包裝進 *ngFor 元素。 這個元素可以使用ng-container,以免引入一個新的HTML層級    5.使用TemplateRef取得<ng-template>的内容,并通過ViewContainerRef來通路這個視圖容器。 

總結: 結構型指令可以操縱 HTML 的元素布局。

當沒有合适的容器元素時,可以使用<ng-container>對元素進行分組。

Angular 會把星号(*)文法解開成<ng-template>。

内置指令NgIf、NgFor和NgSwitch的工作原理。

微文法如何展開成<ng-template>。

寫了一個自定義結構型指令 —— UnlessDirective。 angular預設是單資料綁定   angularjs預設是雙資料綁定  。 屬性指令意味着标簽的左右都為元件的屬性 。