Angular Использовать одну и ту же TemplateRef более чем в одном месте одновременно - Clone TemplateRef?

Я пытаюсь создать компонент с множественным выбором, который может принимать шаблон для каждого элемента опции выбора. В основном это работает, шаблоны берутся из ng-content в компоненте option и отображаются в штрафе «выберите всплывающее окно».

Angular Использовать одну и ту же TemplateRef более чем в одном месте одновременно - Clone TemplateRef?

У меня возникают проблемы при попытке отобразить выбранный параметр в компоненте выбора. Кажется, что шаблон может отображаться только в одном месте за раз, поэтому, когда выбранный параметр отображается в списке выбора, он удаляется из всплывающего окна.

Angular Использовать одну и ту же TemplateRef более чем в одном месте одновременно - Clone TemplateRef?

Есть ли способ клонировать компонент TemplateRef? На самом деле я не возражаю, если контекст не обновляется для шаблона, поскольку в настоящее время я ничего из него не использую, только шаблон.

Включив несколько фрагментов кода ниже для ясности, я думаю, что это нормально.

Использование в somepage.component.html:

<my-select [(value)] = "vals">
    <my-option *ngFor = "let x of [1,2,3]" [value] = "x">Option {{x}}</my-option>
</my-select>`

my-select.component.html

...
<ng-container [ngTemplateOutlet] = "getSelectedOptionTemplate()"></ng-container>
...

my-select.component.ts

getSelectedOptionTemplate(){
    // Some way to clone here could solve the issue?
    return this.getSelectedOption().template;
}

my-select-overlay.component.html

...
<ng-container *ngFor = "let opt of options;">
    <ng-container [ngTemplateOutlet] = "getTemplate(opt)"></ng-container>
</ng-container>
...

my-option.component.html

<ng-template>
    <ng-content></ng-content>
</ng-template>

my-option.component.ts

...
@ViewChild(TemplateRef)
template: TemplateRef<any>;
...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
5
0
328
1

Ответы 1

Я нашел на Github решение этой проблемы.

Кажется, что использование того же TemplateRef работает, когда ng-templateоборачивает компонент, который содержит ng-content.

Представьте, что нам нужно получить что-то вроде:

<ng-template>
   <my-option>
      ... option content ...(<ng-content></ng-content>)
   </my-option>
</ng-template>`

Чтобы получить структуру выше, мы можем реализовать структурная директива. Из документов:

Angular transforms the asterisk in front of a structural directive into an <ng-template> that surrounds the host element and its descendants.

Код для структурной директивы будет:

@Directive({
  selector: "[appOptionTemplate]"
})
export class OptionTemplateDirective {
  @Input("appOptionTemplate")
  value: any;

  constructor(
    public templateRef: TemplateRef<any>
  ) {}
}

(обратите внимание на следующее:

  • внедрение templateRef в конструктор
  • свойство Input)

При заполнении параметров выбора мы будем использовать следующее:

<app-select>
  <ng-container *ngFor = "let x of [1,2,3]; let i=index;">
    <app-option *appOptionTemplate = "x">
      Option {{x}}
    </app-option>
  </ng-container>
</app-select>

Теперь мы будем использовать структурную директиву для запроса содержимого в компоненте select:

@ContentChildren(OptionTemplateDirective)
options: QueryList<OptionTemplateDirective>;

А для отображения опции мы будем использовать:

<ng-container *ngTemplateOutlet = "option.templateRef"></ng-container>

Пример:https://stackblitz.com/edit/angular-ivy-pues8t


Github тема:

https://github.com/angular/angular/issues/37995


Подробнее о структурных директивах:

https://angular.io/guide/structural-directives

Другие вопросы по теме