Получить шаблон ViewChildren по идентификатору - PullRequest
0 голосов
/ 12 февраля 2020

В моем компоненте я получаю список шаблонов разметки с помощью ViewChildren:

@ViewChildren(TemplateRef) private _templates: QueryList<TemplateRef<unknown>>;

В Angular8 я не смог отфильтровать их по Id, поэтому мне нужно было искать внутреннее свойство - что было как-то немного странно:

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>

1 Ответ

1 голос
/ 12 февраля 2020

Чистое решение для вашего сценария - создать директиву 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-run Пример

...