angular - 按 ID 获取 ViewChildren 模板
问题描述
在我的组件中,我使用 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,这不再适用了。我检查了对象并发现了一个新的“hack”:
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。
推荐阅读
- mstest - MStest 中的 Textcontext 属性给出空引用异常
- javascript - Javascript 数学文本字段
- vba - 在 VBA 中将单元格的值写入另一个 Excel
- java - Android MediaRecorder Fragment 如何保持同一个实例
- angular - `sass` 在 css 中使用大括号时抛出错误
- javascript - 如何将模型对话框定位到中心?
- kinect - 从 Kinect 检测到的帧速率不足
- c - 主进程和启动进程之间的不对称
- java - 使用 Hibernate 的 JPQL 类型化查询中的时间戳文字
- vb.net - 生成像“50VIABC001”这样的代码,如果值“ABC”再次出现而不是附加“002”、“003”等等......?