问题
In my component I get a list of its markup templates by using ViewChildren:
@ViewChildren(TemplateRef) private _templates: QueryList<TemplateRef<unknown>>;
In Angular8 I was not able to filter them by an Id, so i needed to look for an internal property - which was somehow a bit hacky:
let template = this._templates.find(t => (<any>t)._def.references[id]) : null;
Now, with Angular 9, this doesn't work anymore. I checked the object and found a new "hack":
this._templates.find(t => (<any>t)._declarationTContainer?.localNames?.includes(id)) : null;
But is there any new or clean solution for this scenario?
Still hoping for a solution that works without a custom Directive, eg. MatTab probably does something similar, too:
<mat-tab>
<ng-template mat-tab-label>
...
</ng-template>
<ng-template matTabContent>
...
</ng-template>
</mat-tab>
回答1:
A clean solution for your scenario is to create a NgTemplateNameDirective
directive with ng-template[name]
selector:
import { Directive, Input, TemplateRef } from '@angular/core';
@Directive({
selector: 'ng-template[name]'
})
export class NgTemplateNameDirective {
@Input() name: string;
constructor(public template: TemplateRef<any>) { }
}
after that create templates like:
<ng-template name="t1"></ng-template>
<ng-template name="t2"></ng-template>
then query NgTemplateNameDirective
instead of TemplateRef
:
@ViewChildren(NgTemplateNameDirective) private _templates: QueryList<NgTemplateNameDirective>;
and finally search your template by name
getTemplateRefByName(name: string): TemplateRef<any> {
const dir = this._templates.find(dir => dir.name === name);
return dir ? dir.template : null
}
Works fine in both view engines: ViewEngine and Ivy.
Ng-run Example
来源:https://stackoverflow.com/questions/60191471/get-viewchildren-template-by-id