首頁  >  文章  >  web前端  >  聊聊Angular中NgTemplateOutlet指令的理解和用法

聊聊Angular中NgTemplateOutlet指令的理解和用法

青灯夜游
青灯夜游轉載
2021-10-19 10:14:002537瀏覽

本篇文章帶大家來了解Angular中NgTemplateOutlet指令,介紹NgTemplateOutlet這個結構性指令的理解與應用,希望對大家有幫助!

聊聊Angular中NgTemplateOutlet指令的理解和用法

最近在看一個訓練專案的時候有看到這個NgTemplateOutlet這個結構性指令,但是我之前沒接觸過,不知道這東西是怎麼用的,然後,我去官網上去搜了一下這個api(官網連結點這裡)。

但是它的這個api說明我看不懂,不知道這個什麼所謂的上下文物件是啥,也不知道這個let變數又是啥。然後經過我一整天的翻文檔,記筆記,終於搞明白了這是什麼東西了,沒有搞明白的小伙伴可以參考一下我的上一篇文章:【Angular學習】關於模板輸入變量(let-變數)的理解

這篇文章就只是說一下NgTemplateOutlet的用法和使用場景。 【相關教學推薦:《angular教學》】

使用方法

這個api按照官網的說法是這樣的:

根據一個提前備好的TemplateRef 插入一個內嵌視圖。

我給它翻譯一下:讓NgTemplateOutlet的宿主元素變成一個內嵌視圖-這個內嵌視圖是根據一個提前定義好的templateRef模板引用生成的。而宿主元素無論是什麼元素,都不會被渲染出來。

我們將官網的範例改一下(因為官網的人命我看不懂):

@Component({
  selector: 'ng-template-outlet-example',
  template: `
    <ng-container *ngTemplateOutlet="one"></ng-container>
    <hr>
    <ng-container *ngTemplateOutlet="two; context: myContext"></ng-container>
    <hr>
    <ng-container *ngTemplateOutlet="three; context: myContext"></ng-container>
    <hr>

    <ng-template #one><span>Hello</span></ng-template>
    <ng-template #two let-name><span>Hello {{name}}!</span></ng-template>
    <ng-template #three let-person="lastName">My name is <span>LeBron {{person}}!</span></ng-template>
`
})
export class NgTemplateOutletExample {
  myContext = {$implicit: &#39;World&#39;, lastName: &#39;James&#39;};
}

一個宿主元素可以使用ngTemplateOutlet這個結構性指令,使自己變成任意的一個<ng-template></ng-template>模板產生的內嵌視圖。並且可以給其設定上下文物件。然後我們在這個模板中可以使用let-變數這個模板輸入變數來取得上下文物件中的值,這個模板更有彈性。

應用程式場景

類似於ng-zorro這個框架的分頁元件Pagination官網連結)。如果我們對預設上一頁和下一頁的樣式或結構不滿意,想要自己調整的話,我們可以提供一個輸入屬性(@Input定義的屬性),來接收一個模板,並且為其提供所必須的屬性或方法。這樣的話,我們就可以在不修改元件原始碼的情況下實現元件的複用。

Demo

我們先定義一個子元件HeroDisplayCard,角色的展示介面

@Component({
  selector:&#39;app-hero-display-card&#39;,
  template:`
    <h2 [style]="{textAlign:&#39;center&#39;}">角色列表</h2>
    <ul class="hero-card-box">
      <li class="hero-card-item" *ngFor="let h of heroesList">
        <p [style]="{textAlign:&#39;center&#39;}">
          角色id:{{h.id}}--
          角色名字:{{h.name}}--
          角色属性:{{h.features}}
        </p>
      </li>
    </ul>
  `,
  styles:[
    `.hero-card-box{
      width: 600px;
      margin: 10px auto;
    }
    .hero-card-item{
      list-style: none;
    }
    `
  ]
})
export class HeroDisplayCard {
  public heroesList = [
    {id:&#39;013&#39;,name:&#39;钟离&#39;,features:&#39;rock&#39;},
    {id:&#39;061&#39;,name:&#39;烟绯&#39;,features:&#39;fire&#39;},
    {id:&#39;022&#39;,name:&#39;迪奥娜&#39;,features:&#39;ice&#39;},
    {id:&#39;004&#39;,name:&#39;诺艾尔&#39;,features:&#39;rock&#39;},
  ]
}

然後將這個元件引入一個父元件當中:

@Component({
  selector:&#39;app-templateoutlet-app-demo&#39;,
  template:`
    <app-hero-display-card></app-hero-display-card>
  `
})
export class TemplateOutletAppDemoComponent {}

程式碼運行一下,效果如圖:

聊聊Angular中NgTemplateOutlet指令的理解和用法

#我覺得這個li的樣式實在是太醜了,而且順序也不太對。我希望把角色屬性調到角色名字之前。這樣的話,如果只是單純的透過輸入屬性來更改樣式的話就會變得很麻煩,我們可能需要定義非常多的變數來供使用者選擇,這樣的話有點得不償失。那我們何不直接提供一個範本給使用者,我們只需要提供必要的資料就可以了。樣式,排版這些自由交給使用者。

那麼對於子元件HeroDisplayCard我們可以這麼改:

@Component({
  selector:&#39;app-hero-display-card&#39;,
  template:`
    <h2 [style]="{textAlign:&#39;center&#39;}">角色列表</h2>
    <ul class="hero-card-box">
      <ng-container *ngFor="let h of heroesList">
        <!-- 如果没有传入cardItemTemplate则显示默认 -->
        <li class="hero-card-item" *ngIf="!cardItemTemplate">
          <p [style]="{textAlign:&#39;center&#39;}">
            角色id:{{h.id}}--
            角色名字:{{h.name}}--
            角色属性:{{h.features}}
          </p>
        </li>
        <!-- 如果传入了自定义模板,则显示出来,鉴于angular的结构型指令不能在同一个宿主元素上的规定,于是这样写 -->
        <ng-container *ngIf="cardItemTemplate">
		  <!-- 将自定义模板的上下文对象设置为h -->
          <ng-container *ngTemplateOutlet="cardItemTemplate;context:h"></ng-container>
        </ng-container>
      </ng-container>
    </ul>
  `,
  styles:[ //省略 ]
})
export class HeroDisplayCard {
  @Input() cardItemTemplate:TemplateRef<any>;
  public heroesList = [ // 省略]
}

然後我們在父元件中將自訂的範本傳入進去:

@Component({
  selector:&#39;app-templateoutlet-app-demo&#39;,
  template:`
    <app-hero-display-card [cardItemTemplate]="myCardTemplate"></app-hero-display-card>
	<!-- 将模板引用变量myCardTemplate传入子组件 -->
    <ng-template #myCardTemplate let-id="id" let-name="name" let-features="features">
      <li class="hero-card-custom-item">
        <p>角色id:<span>{{id}}</span></p>
        <p>角色属性:<span>{{features}}</span></p>
        <p>角色名字:<span>{{name}}</span></p>
      </li>
    </ng-template>
  `,
  styles:[
    //在这里写自定义模板的样式  
    `.hero-card-custom-item{
      width: 100%;
      height: 35px;
      border: 1px solid #999999;
      border-radius: 5px;
      display: flex;
      justify-content:space-around;
      align-items: center;
      margin: 10px 0;
    }
    .hero-card-custom-item p {
      width: 30%;
      margin: 0;
      font-size: 20px;
      color: #666666;
    }
    .hero-card-custom-item p span {
      color: red;
    }`
  ]
})
export class TemplateOutletAppDemoComponent {}

然後運行一下,效果如圖(其實還是很醜):

聊聊Angular中NgTemplateOutlet指令的理解和用法

#總結

使用NgTemplateOutlet這個結構性指令可以增強我們子元件的封裝程度,避免需要定義大量的輸入屬性,導致父元件的模板看起來臃腫不堪。

更多程式相關知識,請造訪:程式設計入門! !

以上是聊聊Angular中NgTemplateOutlet指令的理解和用法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除