带有模板出口的角组件

时间:2018-11-15 03:16:48

标签: angular typescript

我有一个问题组件,该组件具有多个实现,但包含一个通用的标题组件。

我的愿望是创建一个组件,以便给定问题模型,模板将输出正确类型的问题。

我已经看到了ngTemplateOutlet的想法,但是关于它如何工作的文档很难理解(也许不适合您,但对我来说),并且我无法通过查看示例来确定实现这一点。我认为我不必在哪里重新发明轮子,这似乎是常见的要求。

我以前的尝试包括一个[ngSwitch]容器,其中包含许多不同的*ngSwitchCase,但是如果我可以在外部定义模板并让QuestionComponent知道来自questionType的映射,那将是理想的选择到可用的ng-template

例如

export class question { 
  constructor(public title: string, public questionType: string, public answer: any) {} 
}

@Component({
  selector: 'app-question',
  template: `
    <div class="question">
      <p>{{q.title}}</p>
      <ng-container [ngTemplateOutlet]="theRightTemplate">
      </ng-container>
    </div>
  `})
export class QuestionComponent {
  @Input()
  question: Question;
}

我目前正在使用Angular 7

有人可以帮我弄清楚如何实现这一目标吗?

3 个答案:

答案 0 :(得分:0)

好的,我给你举个例子并向它解释:

链接:https://github.com/100cm/at-ui-angular/blob/master/src/app/components/switch/switch.component.ts

对于您的代码,我们必须定义一个@Input变量

export class question { 
  constructor(public title: string, public questionType: string, public answer: any) {} 
}

@Component({
  selector: 'app-question',
  template: `
    <div class="question">
      <p>{{q.title}}</p>
      <ng-container [ngTemplateOutlet]="theRightTemplate">
      </ng-container>
    </div>
  `})
export class QuestionComponent {
  @Input()
  question: Question;
  @Input()
  myTemplate:TemplateRef
}

然后将<ng-container>更改为<ng-template>(我认为<ng-container>不能用于模板出口

<ng-template [ngTemplateOutlet]="myTemplate">

好,那就立即使用您的<app-question>

what_ever_html:

<app-question [myTemplate]="my_template"></app-question>

<ng-template #my_template> i am worked now !</ng-template>

希望这对您有帮助!

答案 1 :(得分:0)

使用模板制作动态组件时,有两点很重要。

  1. Template-第一个是模板本身,需要注入,这里需要注意的重要一点是,它需要包含附加信息的context,在您的情况下,question详细信息。
  2. ngTemplateOutlet-需要在其中注入模板的位置。它接受templatecontext作为模板。

这是简单的示例-

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
  <ng-container *ngTemplateOutlet="templateRef; context: {entry: entry}"></ng-container>
  <ng-template #templateRef let-entry="entry">My entry is {{entry | json}}</ng-template>
  `,
})
export class AppComponent  {
  entry = {
    label: 'This is a label',
    description: 'Desc',
  }
}

示例1- https://stackblitz.com/edit/ng-template-outlet-6pzddz

示例2- https://stackblitz.com/edit/angular-reusable-components-ngtemplateoutlet-5nidmd

答案 2 :(得分:0)

您可以在@ContentChild('tableHeader') header: TemplateRef<any>;中使用QuestionComponent,也可以使用ContentChild从内容DOM中获取与选择器匹配的第一个元素或指令。

如果内容DOM更改,并且有一个新的子项与选择器匹配,则该属性将被更新。

您的孩子component.html读为

<ng-template [ngTemplateOutlet]="header"></ng-template> <ng-template [ngTemplateOutlet]="body"></ng-template>

[ngTemplateOutlet]将读取属性值并将内容粘贴到指定模板中的位置

最后,当您从父组件中引用内容时,它将与上述模板一起放置

将内容从父母传递给孩子的方法

<app-question> <ng-template #tableHeader></ng-template> <ng-template #body></ng-template> </app-question>

<ng-template>中的任何内容都将放置在子component

在子组件中,您可以添加尽可能多的模板,在这些模板中,所有模板将与从父组件传递来的内容一起放置-这是将内容从父项传递给子组件的另一种方式-希望这会有所帮助-谢谢Happy编码! !

点击here供参考