在我的组件中,我使用 ViewChildren 获取其标记模板的列表:
@ViewChildren(TemplateRef) private _templates: QueryList<TemplateRef<unknown>>;
在 Angular8 中,我无法通过 Id 过滤它们,所以我需要寻找一个内部属性 - 这在某种程度上有点 hacky:
let template = this._templates.find(t => (<any>t)._def.references[id]) : null;
现在,有了 Angular 9,这种情况就不再适用了。我检查了该对象并发现了一个新的“黑客”:
this._templates.find(t => (<any>t)._declarationTContainer?.localNames?.includes(id)) : null;
但是对于这种情况有什么新的或干净的解决方案吗?
仍然希望有一个无需自定义指令即可工作的解决方案,例如。 MatTab 可能也会做类似的事情:
<mat-tab>
<ng-template mat-tab-label>
...
</ng-template>
<ng-template matTabContent>
...
</ng-template>
</mat-tab>
针对您的场景的一个干净的解决方案是创建一个NgTemplateNameDirective
指令与ng-template[name]
选择器:
import { Directive, Input, TemplateRef } from '@angular/core';
@Directive({
selector: 'ng-template[name]'
})
export class NgTemplateNameDirective {
@Input() name: string;
constructor(public template: TemplateRef<any>) { }
}
之后创建模板,例如:
<ng-template name="t1"></ng-template>
<ng-template name="t2"></ng-template>
然后查询NgTemplateNameDirective
代替TemplateRef
:
@ViewChildren(NgTemplateNameDirective) private _templates: QueryList<NgTemplateNameDirective>;
最后按名称搜索您的模板
getTemplateRefByName(name: string): TemplateRef<any> {
const dir = this._templates.find(dir => dir.name === name);
return dir ? dir.template : null
}
在两种视图引擎中都可以正常工作:ViewEngine 和 Ivy.
NG 运行示例 https://ng-run.com/edit/5OGMZ08gP2Hpvk26pBDt?open=app%2Fapp.component.ts
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)