天天看点

angular6.x中ngTemplateOutlet指令的使用

在使用angular进行开发的时候,通过属性绑定向组件内部传值的方式,有时候并不能完全满足需求,比如我们写了一个公共组件,但是某个模板使用这个公共组件的时候,需要在其内部添加一些标签内容,这种情况下,除了使用

ngIf

/

ngSwitch

预先在组件内部定义之外,就可以利用

ngTemplateOutlet

指令向组件传入内容.

ngTemplateOutlet

指令类似于angularjs中的

ng-transclude

,vuejs中的

slot

.

ngTemplateOutlet

是结构型指令,需要绑定一个

TemplateRef

类型的实例.

使用方式如下:

@Component({
  selector: 'app',
  template: `
    <h1>Angular's template outlet and lifecycle example</h1>
    <app-content [templateRef]="nestedComponentRef"></app-content>
    <ng-template #nestedComponentRef let-name>
      <span>Hello {{name}}!</span>
      <app-nested-component></app-nested-component>
    </ng-template>
  `,
})
export class App {}
@Component({
  selector: 'app-content',
  template: `
    <button (click)="display = !display">Toggle content</button>
    <template 
        *ngIf="display" 
        *ngTemplateOutlet="templateRef context: myContext">
    </template>
  `,
})
export class Content {
  display = false;
  @Input() templateRef: TemplateRef;
  myContext = {$implicit: 'World', localSk: 'Svet'};
}
@Component({
  selector: 'app-nested-component',
  template: `
    <b>Hello World!</b>
  `,
})
export class NestedComponent implements OnDestroy, OnInit {
  
  ngOnInit() {
    alert('app-nested-component initialized!');
  }
  
  ngOnDestroy() {
    alert('app-nested-component destroyed!');
  }
  
}
           

代码中除了根组件外定义了两个组件

  • 容器组件:

    app-content

  • 传递进去的内容组件:

    app-nested-component

app-content

组件接收一个

TemplateRef

类型的输入属性

templateRef

,并在模板中将其绑定到了

ngTemplateOutlet

指令,当组件接收到

templateRef

属性时,就会将其渲染到

ngTemplateOutlet

指令所在的位置.

上例中,

app-content

组件

templateRef

属性的来源,是在根组件的模板内,直接通过

#

符号获取到了

app-nested-component

组件所在

<ng-template>

的引用并传入的.

在实际应用中,除了这种方式,也可以直接在组件内部获取

TemplateRef

类型的属性并绑定到

ngTemplateOutlet

指令.

比如在容器组件为模态框的情况下,并不能通过模板传值,就可以使用下面这种方式:

@ViewChild('temp') temp: TemplateRef<any>

 openDialog(){
   this.dialog.open(ViewDialogComponent, {data: this.temp)
 }
           

在容器组件中还可以定义被传递内容的上下文(上例

app-content

组件中的

myContext

属性),其中的

$implicit

属性作为默认值,在被传递的内容中可以以重命名的方式访问(上例

let-name

),对于上下文中其他的属性,就需要通过

let-属性名

的方式访问了.

继续阅读