Как преобразовать строку в экземпляр шаблона ссылки?
Я настраиваю 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
имеет тип строки, я подозреваю, что это не разрешается в переменную templateReference.
Как я могу преобразовать строку в экземпляр templateReference?
Демонстрация - см. Эту ссылку, например, и проверьте консоль на наличие ошибки
3 ответа
Ваш вопрос на самом деле, как мы рассматриваем строку как переменную templateReferance в шаблоне HTML. Если вам не нужно обращаться с этим способом, вы можете просто попробовать это:
@ViewChild('templateOne') templateOne: ElementRef;
@ViewChild('templateTwo') templateTwo: ElementRef;
list;
ngOnInit() {
this.list = [ {type: this.templateOne}, {type: this.templateTwo} ];
}
По сути, вы можете создать чистую функцию, которая выполняет отображение / преобразование:
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
}
Вот рабочий пример:
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}];
}
}