溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

詳解Angular 自定義結構指令

發布時間:2020-09-05 22:56:33 來源:腳本之家 閱讀:191 作者:Keriy 欄目:web開發

1. <ng-template>元素

import { Component, TemplateRef, ViewContainerRef, ViewChild,
 AfterViewInit } from '@angular/core';
@Component({
 selector: 'app-code404',
 template: `
 <!-- 這里使用一個模板變量,在組件中使用@ViewChild裝飾器獲取模板元素-->
  <ng-template #tpl>
   Big Keriy !
  </ng-template>
 `,
})
export class Code404Component implements AfterViewInit{

 // @ViewChild 裝飾器獲取模板元素
 @ViewChild('tpl')
 tplRef: TemplateRef<any>;
 constructor(private vcRef: ViewContainerRef) {}
 ngAfterViewInit() {

  // 使用ViewContainerRef對象的createEmbeddedView方法創建內嵌視圖。
  this.vcRef.createEmbeddedView(this.tplRef);
 } }

這樣其實我們在視圖中就得到了一個什么...啊,就是一個'Big Keriy !'的字符串。

2. ngTemplateOutlet指令

a. ngTemplateOutlet

和routerOutlet是一個意思,將視圖(<ng-template>標簽中的內容)放到對應的ngTemplateoutlet下面。

import { Component } from '@angular/core';
 @Component({
  selector: 'app-code404',
  template: `
   <ng-template #stpl>
    Hello, Semlinker!
   </ng-template>
   <ng-template #atpl>
    Big Keriy !
   </ng-template>
   <div [ngTemplateOutlet]="atpl"></div>
   <div [ngTemplateOutlet]="stpl"></div>
`, })
 export class Code404Component { }

最終的視圖應該是:

Big Keriy !
Hello, Semlinker!

b. ngOutletContex

看名字就知道意思。

ngTemplateOutlet指令基于TemplateRef對象,在使用ngTemplateOutlet指令時,可以通過ngTemplateOutletContext屬性來設置來設置EmbeddedViewRef的上下文對象??梢允褂胠et語法來聲明綁定上下文對象屬性名。

import { Component, TemplateRef, ViewContainerRef, ViewChild,
 AfterViewInit } from '@angular/core';
@Component({
 selector: 'app-code404',
 template: `
  <!-- 這里的messagey映射到下面context中message 再使用插值表達式的方式顯示message的值 -->
  <ng-template #stpl let-message="message">
   <p>{{message}}</p>
  </ng-template>
  <!-- 這里的messagey映射到下面context中message , let-msg是一種與語法糖的方式變量名是msg-->
  <ng-template #atpl let-msg="message">
   <p>{{msg}}</p>
  </ng-template>
  <!-- 若不指定變量值那么將顯示 $implicit 的值-->
  <ng-template #otpl let-msg>
   <p>{{msg}}</p>
  </ng-template>
  <div [ngTemplateOutlet]="atpl"
     // 這里ngOutletContext綁定的是context對象
     [ngOutletContext]="context">
  </div>
  <div [ngTemplateOutlet]="stpl"
     [ngOutletContext]="context">
  </div>
  <div [ngTemplateOutlet]="otpl"
     [ngOutletContext]="context">
  </div>
 `,
})
export class Code404Component implements AfterViewInit{
 @ViewChild('tpl')
 tplRef: TemplateRef<any>;
 constructor(private vcRef: ViewContainerRef) {}
 ngAfterViewInit() {
  this.vcRef.createEmbeddedView(this.tplRef);
 }
 context = { message: 'Hello ngOutletContext!',
  $implicit: 'great, Semlinker!' };
  // 這里的$implicit是固定寫法
}

先看輸出的視圖:

Hello ngOutletContext!
Hello ngOutletContext!
Hello, Semlinker!

3. ngComponentOutlet指令

聽著名字就很爽,這不是插入視圖的,是插入組件的!

該指令使用聲明的方式,動態加載組件。

先寫組件,里面有兩個。。組件:

 @Component({
  selector: 'alert-success',
  template: `
   <p>Alert success</p>
  `,
 })
 export class AlertSuccessComponent { }
 @Component({
  selector: 'alert-danger',
  template: `
   <p>Alert danger</p>
  `,
 })
 export class AlertDangerComponent { }
 @Component({
  selector: 'my-app',
  template: `
   <h2>Angular version 4</h2>
   <ng-container *ngComponentOutlet="alert"></ng-container>
   <button (click)="changeComponent()">Change component</button>
 `, })
 export class AppComponent {
   alert = AlertSuccessComponent;
  changeComponent() {
   this.alert = AlertDangerComponent;
 } 
}

當然,還需要在模塊中聲明入口:

// app.module.ts
@NgModule({
  // ...
  declarations: [
   AppComponent,
   SignUpComponent,
   AlertSuccessComponent,
   AlertDangerComponent
  ],
  entryComponents: [    // 這里面寫指令中呀用到的組件
   AlertSuccessComponent,
   AlertDangerComponent
],
// ...
})

這樣就可以使用ngComponentOutlet指令來插入組件玩耍了:

<!-- 簡單語法 -->
<ng-container *ngComponentOutlet="componentTypeExpression"></ng-container>

<!-- 完整語法 -->
<ng-container *ngComponentOutlet="componentTypeExpression;
   injector: injectorExpression;
   content: contentNodesExpression;">
</ng-container>

這是一個完整語法簡單的例子:

// ...
@Component({
 selector: 'ng-component-outlet-complete-example',
 template: `
  <ng-container *ngComponentOutlet="CompleteComponent; 
                   injector: myInjector; 
                   content: myContent"></ng-container>`
})
class NgTemplateOutletCompleteExample {
 // This field is necessary to expose CompleteComponent to the template.
 CompleteComponent = CompleteComponent;
 myInjector: Injector;

 myContent = [[document.createTextNode('Ahoj')], [document.createTextNode('Svet')]];

 constructor(injector: Injector) {
  this.myInjector = ReflectiveInjector.resolveAndCreate([Greeter], injector);
 }
}

4. 創建結構指令

也想不出來一個什么好例子,抄一個例子過來:

// uless.directive.ts

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
 @Directive({
   selector: '[exeUnless]'
 })
 export class UnlessDirective {
   @Input('exeUnless')
   set condition(newCondition: boolean) { // set condition
     if (!newCondition) {
       this.viewContainer.createEmbeddedView(this.templateRef);
     } else {
       this.viewContainer.clear();
     } 
   }
   constructor(private templateRef: TemplateRef<any>,
     private viewContainer: ViewContainerRef) {
   } 
 }


 import { Component } from '@angular/core';
 @Component({
  selector: 'app-root',
  template: `
   <h3 *exeUnless="condition">Hello, Semlinker!</h3>
  `,
 })
 export class AppComponent {
  condition: boolean = false;
 }


 // app.component.ts

 import { Component } from '@angular/core';
 @Component({
  selector: 'app-root',
  template: `
   <h3 *exeUnless="condition">Hello, Semlinker!</h3>
  `,
 })
 export class AppComponent {
  condition: boolean = false;
 }

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女