【问题标题】:Passing a template as content, which is in turn passed to another component将模板作为内容传递,然后将其传递给另一个组件
【发布时间】:2017-05-05 15:39:31
【问题描述】:

使用 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 相同,只是它们的名称不同。它们具有与my-component 相同的value 输入,并且还接收一个模板作为它们的内容。这就是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/

我做错了什么?

【问题讨论】:

  • 没有[ngOutletContext]。这是[ngTemplateOutletContext]

标签: angular


【解决方案1】:

想法是您需要将模板向下传递到层次结构树。 在此处查看 plunker:https://plnkr.co/edit/hwww2QXDh9Je5Bc9ld3O?p=preview

在我的原生组件中:

<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;

必须牢记这一点。 &lt;ng-template&gt; 必须需要一个容器来输出其内容。默认情况下它隐藏在 HTML 中。 https://angular.io/docs/ts/latest/guide/structural-directives.html#!#template

【讨论】:

  • 谢谢,但那是在 my-native-component 中定义一个新模板。你知道如何让my-native-component 渲染传递给my-component 的模板吗?
  • 啊,我没想过将引​​用作为输入传递。谢谢!
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    您应该使用以下之一:

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

    更多信息请见this link

    【讨论】:

      猜你喜欢
      • 2018-10-02
      • 1970-01-01
      • 2023-01-30
      • 1970-01-01
      • 2021-10-29
      • 2014-03-23
      • 1970-01-01
      • 1970-01-01
      • 2021-12-31
      相关资源
      最近更新 更多