Как преобразовать строку в экземпляр шаблона ссылки? - PullRequest
0 голосов
/ 06 мая 2019

Я настраиваю ngTemplateOutlet внутри * ngFor как в следующем фрагменте кода

  <ul>
    <li *ngFor="let item of list">
      <ng-container [ngTemplateOutlet]="item.type"></ng-container>
    </li>
  </ul>

Где list = [ {type: 'templateOne'}, {type: 'templateTwo'} ] и я определил шаблоны, как показано ниже.

<ng-template #templateOne></ng-template>
<ng-template #templateTwo></ng-template>

Приведенный выше фрагмент шаблона выдает ошибку с указанным ниже сообщением

TypeError: templateRef.createEmbeddedView is not a function
    at ViewContainerRef_.push../node_modules/@angular/core/fesm5/core.js.ViewContainerRef_.createEmbeddedView (core.js:21600)
    at NgTemplateOutlet.push../node_modules/@angular/common/fesm5/common.js.NgTemplateOutlet.ngOnChanges (common.js:4026)
    at checkAndUpdateDirectiveInline (core.js:22085)

Поскольку item.type используется в ngTemplateOutlet, имеет тип string, я подозреваю, что он не разрешается в переменную templateReference.

Как я могу преобразовать строку в экземпляр templateReference?

Демонстрация - См., Например, эту ссылку и проверьте консоль на наличие ошибки

Ответы [ 3 ]

0 голосов
/ 06 мая 2019

Ваш вопрос на самом деле, как мы рассматриваем строку как переменную templateReferance в шаблоне html.Если вам не нужно обращаться с этим способом, вы можете просто попробовать это:

 @ViewChild('templateOne') templateOne: ElementRef;
 @ViewChild('templateTwo') templateTwo: ElementRef;
  list;
  ngOnInit() {
    this.list = [ {type: this.templateOne}, {type: this.templateTwo} ];
  }
0 голосов
/ 10 мая 2019

По сути, вы можете создать чистую функцию, которая выполняет отображение / преобразование:

public map(type:string, ref1:TemplateRef, ref2:TemplateRef):TemplateRef {
   switch(type) {
      case 'templateTwo':
        return ref1;
      case 'templateTwo':
        return ref2;
      default:
        return ref1;
   }
}

Шаблон:

<ul>
    <li *ngFor="let item of list">
      <ng-container [ngTemplateOutlet]="map(item.type, templateOne, templateTwo)"></ng-container>
    </li>
</ul>

В противном случае вам потребуется доступ к шаблону context:

public map(type:string):TemplateRef {
   return (this as any)[type]; // may break in future
}
0 голосов
/ 06 мая 2019

Вот рабочий пример:

    import { Component,ViewChild,TemplateRef,OnInit } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
  <ul>
     <li *ngFor="let item of list;let i = index">
      <ng-container [ngTemplateOutlet]="list[i].type"></ng-container>
    </li>
  </ul>
  <ng-template #templateOne>Template One</ng-template>
  <ng-template #templateTwo>Template Two</ng-template>
  `,
})
export class AppComponent  implements OnInit {
  @ViewChild('templateTwo', {read: TemplateRef}) tpl1: TemplateRef<any>;
  @ViewChild('templateOne', {read: TemplateRef}) tpl2: TemplateRef<any>;
  list;

    ngOnInit() {
      this.list=[{"type":this.tpl1},{"type":this.tpl2}];
    }

}

Ссылочная ссылка

Рабочий пример stackblitz

...