将模板作为内容传递,然后将其传递给另一个组件

时间:2017-05-05 15:39:31

标签: angular

使用Angular 4.0.3

我正在创建一个组件my-component,其输入为value,并作为内容传递ng-template。示例用法是:

<my-component [value]="value">
  <ng-template let-value>
    <p><strong>Value rendered in user supplied template: {{value}}</strong></p>
  </ng-template>
</my-component>

my-component的工作是确定用户是否在移动设备上。如果是,我们想要呈现my-native-component。否则,它将呈现my-custom-component

到目前为止,my-component的代码是:

@Component({
  selector: 'my-component',
  template: `
  <my-custom-component *ngIf="useCustom" [value]="value">
    <ng-template [ngTemplateOutlet]="templateVariable"></ng-template>
  </my-custom-component>

  <my-native-component *ngIf="!useCustom" [value]="value">
    <ng-template [ngTemplateOutlet]="templateVariable"></ng-template>
  </my-native-component>
  `
})
class MyComponent {
  @ContentChild(TemplateRef)
  private templateVariable: TemplateRef;

  @Input()
  private value: string;

  @Input()
  private useCustom: bool = false;
}

为了使示例简单,没有检查用户是否在移动设备上。而是添加了useCustom输入。

当内容被引用为templateVariable时传递的模板,并通过ng-templatengTemplateOutlet作为新模板传递。

在此示例中,my-native-componentmy-custom-component相同,但名称除外。它们与value具有相同的my-component输入,并且还会收到模板作为其内容。这就是my-native-component的样子:

@Component({
  selector: 'my-native-component',
  template: `
  <h3>my-native-component (value: {{value}})</h3>
  <p>Rendered template:</p>
  <ng-template [ngTemplateOutlet]="templateVariable" [ngOutletContext]="{$implicit: value}"></ng-template>
  <p>Done</p>
  `
})
class MyNativeComponent {
  @ContentChild(TemplateRef)
  private templateVariable: TemplateRef;

  @Input()
  private value: string;
}

当应用程序运行时,传递的模板永远不会呈现,我无法弄清楚原因。也许我错误地理解ng-template

Plunker上提供了完整的可运行代码 - https://embed.plnkr.co/fiDECy5gamOLvjPo2uhN/

我做错了什么?

3 个答案:

答案 0 :(得分:5)

想法是您需要将模板传递给层次结构树。 请参阅此处的plunker:https://plnkr.co/edit/hwww2QXDh9Je5Bc9ld3O?p=preview

在my-native-component中:

<ng-container *ngTemplateOutlet="template; context: {$implicit: value}"></ng-container>

在我的组件中:

<my-native-component *ngIf="!useCustom" [value]="value" [template]="template">
  <ng-template [ngTemplateOutlet]="templateVariable"></ng-template>
</my-native-component>

在我的应用中:

<my-component [value]="value" [useCustom]="false" [template]="test"><!-- toggle useCustom true/false -->
  <ng-template #test let-value>
    <p><strong>Value rendered in user supplied template: {{value}}</strong></p>
  </ng-template>
</my-component>

将其放入组件中以允许传输模板。

@Input()
private template: TemplateRef;

必须记住这一点。 <ng-template>必须有一个容器才能输出其内容。它默认隐藏在HTML中。 https://angular.io/docs/ts/latest/guide/structural-directives.html#!#template

答案 1 :(得分:1)

当您添加ngTemplateOutlet时,它不再是模板,因此组件不会将其视为@ContentChild(TemplateRef)。

 <ng-template [ngTemplateOutlet]="templateVariable"></ng-template>

答案 2 :(得分:0)

可接受的答案是正确的,但它使用的方法与您使用的方法不同。您唯一需要更改的是MyNativeComponent中的HTML模板。

您应该使用以下之一:

<ng-container [ngTemplateOutlet]="templateVariable" [ngTemplateOutletContext]="{$implicit: value}"></ng-container>
<ng-container *ngTemplateOutlet="templateVariable; context: {$implicit: value}"></ng-container>

有关更多信息,请参见this link