【问题标题】:How do I get experimental ngTemplateOutlet to work?如何让实验性 ngTemplateOutlet 工作?
【发布时间】:2017-03-18 01:07:38
【问题描述】:

我正在尝试在 Angular2 中构建一个列表组件,该组件从组件的用户那里获取项目字段的项目、列和模板。所以我正在尝试使用ngTemplateOutletngOutletContext(我读过的是实验性的)。但我无法让它工作。

这是一个简化的组件来演示我正在尝试做的事情:

<div *ngFor="let item of items>
  <span *ngFor="let column of columns>
    <template [ngOutletContext]="{ item: item }" 
              [ngTemplateOutlet]="column.templateRef"></template>
  </span>
</div>

这里是组件的用法:

<my-component [items]="cars" [columns]="carColumns">
  <template #model>{{item.model}}</template>
  <template #color>{{item.color}}</template>
  <template #gearbox>{{item.gearbox}}</template>
</my-component>

这是示例数据:

cars = [
  { model: "volvo", color: "blue", gearbox: "manual" },
  { model: "volvo", color: "yellow", gearbox: "manual" },
  { model: "ford", color: "blue", gearbox: "automatic" },
  { model: "mercedes", color: "silver", gearbox: "automatic" }
];

carColumns = [
  { templateRef: "model" },
  { templateRef: "color" },
  { templateRef: "gearbox" }
];

这是一个 plunker 在根据 Günters 评论调整代码后重现该问题: https://plnkr.co/edit/jB6ueHyEKOjpFZjxpWEv?p=preview

【问题讨论】:

标签: angular


【解决方案1】:

更新 Angular 5

ngOutletContext 更名为ngTemplateOutletContext

另见https://github.com/angular/angular/blob/master/CHANGELOG.md#500-beta5-2017-08-29

原创

不要同时使用[]{{}}。一个或另一个,但不能两者兼而有之。

如果您想传递一个对象,请不要使用{{}},因为{{}} 用于字符串插值。

应该是

[ngTemplateOutlet]="column.templateRef"

Plunker example

【讨论】:

  • 啊,有道理。仍然无法正常工作。现在我得到core.umd.js:3072 ORIGINAL EXCEPTION: templateRef.createEmbeddedView is not a function
  • 请提供 Plunker 进行复制。仅使用一些代码片段很难进行调试。
  • 我添加了一个 plunker。
  • 得出与 PatrickJane 相同的结论,但他使用 Plunker 更快。
  • 感谢您的帮助。这不是比赛。
【解决方案2】:

您需要这样做:

@Component({
  selector: 'my-component',
  template: `
    <div *ngFor="let item of items">
      <span *ngFor="let column of columns">
        <template [ngTemplateOutlet]="column.ref" [ngOutletContext]="{ item: item }"></template>
      </span>
    </div>`
})
export class MyComponent {
  @Input() items: any[];
  @Input() columns: any[];
}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <my-component [items]="cars" [columns]="columns">
        <template #model let-item="item">{{item?.model}}</template>
        <template #color let-item="item">{{item?.color}}</template>
      </my-component>
    </div>`
})
export class App {
  @ViewChild('model') model;
  @ViewChild('color') color;
  cars = [
      { model: "volvo", color: "blue" },
      { model: "saab", color: "yellow" },
      { model: "ford", color: "green" },
      { model: "vw", color: "orange" }
    ];

  ngAfterContentInit() {
    this.columns = [
      { ref: this.model },
      { ref: this.color ]
    ];
  }
}

Plunker

【讨论】:

  • 非常感谢。我离得不远,但足以让我感到头撞墙的冲动。
  • 我很惊讶你需要明确地说let-item="item"。添加一个 let 解决了我遇到的类似问题。你会认为这是暗示的。
  • { ref: this.color ]这里没有括号,4.0以后改
【解决方案3】:

你可以在没有 ngOutletContext 的情况下做到这一点。您必须使用 ng-template 而不是模板。 以下代码对我有用:

app.component.html:

<div>
  <ng-template #c1>
    <app-child1></app-child1>
  </ng-template>
  <app-parent [templateChild1]="c1"></app-parent>
</div>

app-parent 是 app-component 的子组件。 app-child 在 app-component 中声明为模板,该模板在 app-parent 中使用。

app.parent.html:

<p>
  <ng-template [ngTemplateOutlet]="templateChild1"></ng-template>
</p>

app.parent.ts:

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {

  @Input() public templateChild1: TemplateRef<any>;

  public ngOnInit() {
  }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    • 2015-02-15
    • 1970-01-01
    • 2017-02-07
    • 2010-12-03
    • 2018-05-19
    相关资源
    最近更新 更多