我设法使用 TemplateRef 的私有 API 做到了这一点。这是我目前使用的功能:
@ContentChildren(TemplateRef) templates: QueryList<TemplateRef<any>>;
getTemplate(id: string): TemplateRef<any> {
// FIXME: Should not use private API...
return this.templates ? this.templates.find((template: any) =>
template._def.references[id]) : null;
}
但这不适用于生产版本,实际上我发现您的帖子正在寻找另一种解决方案,如果我发现某些东西或向 Angular github 提交功能请求,我会更新。
与此同时,我认为它值得分享。
-- 编辑--
看起来确实有使用结构指令的可能解决方案。
您将在本指南中了解到星号 (*) 是一种方便表示法,而字符串是一种微语法,而不是通常的模板表达式。 Angular 将这个符号脱糖成一个标记的<ng-template>,它围绕着宿主元素及其后代。每个结构指令对该模板执行不同的操作。
Link to documentation
-- 编辑 2--
好的,它适用于检索 TemplateRef 的指令,但目前我使用 id 将它注册到服务,我不再使用 ViewChildren/ContentChildren。我的组件使用 *ngTemplateOutlet 指令然后使用服务检索 TemplateRef。
这是指令源代码:
@Directive({
selector: '[formeTemplate]'
})
export class FormeTemplateDirective {
@Input('formeTemplate') templateId;
constructor(private host: TemplateRef<any>, private service: FormeTemplateService) { }
ngOnInit() {
this.service.register(this.templateId, this.host);
}
}
服务:
@Injectable()
export class FormeTemplateService {
private templates: Array<FormeTemplate>;
constructor() {
this.templates = new Array();
}
register(id: string, ref: TemplateRef<any>) {
this.templates.push(new FormeTemplate(id, ref));
}
getTemplateRef(templateId: string) : TemplateRef<any> {
let template = this.templates.find((template) => template.id === templateId);
return template ? template.ref : null;
}
}