angular中的ng-content

在開發一個前端程序時,肯定會有很多相似的邏輯或布局,這時就需要提取公共組件或樣式來盡可的復用代碼。在angular中,提供了ng-content來更方便的編寫組件和布局。

ng-content

  • 在組件中嵌入內容
  • 在組件中嵌入模板代碼
  • select屬性支持css選擇器(”#id”,”.class”等等)

使用
下面以表單中常見的布局為例:


<form-item>
    <form-item-label>
        手機號碼
    </form-item-label>
    <form-item-wrap>
        <input  name="phone" [(ngModel)]="phone"  placeholder="請輸入手機號"/>
    </form-item-wrap>
</form-item>

我們封裝了三個組件:form-item form-item-label form-item-wrap
我們期望form-item-label中的內容展示頁面文字說明部分,form-item-wrap展示頁面用戶輸入部分。

<form-item>
    <form-item-label>
    <!-- your html code -->
    </form-item-label>
    <form-item-wrap>
    <!-- your html code -->
    </form-item-wrap>
</form-item>

form-item組件代碼:

import { Component, ContentChild } from '@angular/core';
import { FormItemLabelComponent } from './form-item-lable.component';
import { FormItemWrapComponent } from './form-item-wrap.component';
@Component({
  selector: 'form-item',
  templateUrl: './form-item.component.html'
})
export class FormItemComponent {
  @ContentChild(FormItemLabelComponent) itemLabel;
  @ContentChild(FormItemWrapComponent) itemWrap;
}
html:
<div>
    <div class="css實現">
        <ng-content select="form-item-label" *ngIf="itemLabel"></ng-content>
    </div>
    <div class="css實現">
      <ng-content select="form-item-wrap" *ngIf="itemWrap"></ng-content>
    </div>
</div>

form-item-label組件代碼:

import { Component } from '@angular/core';
@Component({
  selector: 'form-item-label',
  template: '<ng-content></ng-content>'
})
export class FormItemLabelComponent {
}

form-item-wrap組件代碼:

import { Component } from '@angular/core';
@Component({
  selector: 'form-item-wrap',
  template: '<ng-content></ng-content>'
})
export class FormItemWrapComponent {
}

在組件form-item中通過ng-content的select屬性(使用的是css的element選擇器)投影form-item-label和form-item-wrap組件內容。

在form-item-label和form-item-wrap中則使用ng-content來嵌入模板代碼,如果沒有ng-content則組件中的模板代碼無法展示。(組件內css樣式不再展示)

ContentChild

  • ContentChild 用來從通過 Content Projection 方式 (ng-content) 設置的視圖中獲取匹配的元素

  • 在父組件的 ngAfterContentInit 生命周期鉤子中才能成功獲取通過 ContentChild 查詢的元素

它和viewChild是不同的

  • ViewChild 用來從模板視圖中獲取匹配的元素
  • 在父組件的 ngAfterViewInit 生命周期鉤子中才能成功獲取通過 ViewChild 查詢的元素

與css直接布局對比優勢

本文中注冊頁面視效是左右布局,有些ux設計可能是上下布局,可能是點擊操作彈出文字說明布局等等,這些布局抽象成建模分為兩部分:文字說明部分和用戶操作部分。使用ng-content編寫組件,實際上相當于頁面領域的建模,form-item-label是文字描述部分,form-item-wrap是用戶操作部分,不論ux ui的設計如何,但是建模是一定的。

組件化的優勢

  1. 犧牲我一個,幸福千萬家
  2. 以表單舉例:設計師要求左邊部分帶必選符號”*“或者”:”,如果是各個業務的開發童鞋來寫,后期設計一旦變更,就會存在更換不及時,整個產品用戶體驗不一致的情況,而如果通過form-item組件內部搞定這件事情,只需要開發這個組件的同事更新組件即可,保證了整體的一致性
  3. 項目團隊有一個css高手保證組件樣式即可,極大的提升開發效率

總結

ng-content是組件化的神器,用好ng-content對一個項目有極大的便利。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,288評論 25 708
  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,796評論 1 92
  • ——被安利之后種草非常想玩甚至想實況的游戲系列之一—— 一個多月前的某一天晚上,很湊巧地趕上了嵐少的直播。 然后就...
    佳木繁玥閱讀 1,095評論 0 4
  • 這一年的8月異常浮躁。 “第9號臺風‘麥莎’在浙江省玉環縣干江鎮正面登陸,隨后橫穿浙江。臺風過處,狂風怒發,海潮翻...
    南呂先生閱讀 590評論 0 51
  • 屬性說明 名稱 物品名稱 價格 價格
    玉面笑客閱讀 5,688評論 1 0