Повторить ng-шаблон с ng-содержимым в качестве тела (создать копию ng-содержимого)

#angular #typescript #primeng #transclusion

#angular #машинописный текст #primeng #преобразование

Вопрос:

Я создаю опцию для добавления пользовательских столбцов в таблицу PrimeNG. Причина, по которой я хочу создать это, заключается в том, что я предлагаю таблицу по умолчанию с множеством уже установленных параметров конфигурации.

Проблема, с которой я сталкиваюсь, заключается в том, что, похоже, я не могу повторить ng-template компонент несколько раз.


Мои версии

  • Angular 7.2.12
  • Primeng 7.1.0
  • @angular/анимации 7.2.12

Чего я хочу достичь

Я хочу создать оболочку, которая упрощает создание столбцов и устраняет необходимость создания нескольких шаблонов в теле таблицы.

Пример того, что я хочу упростить:

 <table>
 <!-- Row 1 -->
 <ng-template #header><th>edit></th></ng-template>
 <ng-template #content><button>edit></button></ng-template>

 <!-- Row 2 -->
 <ng-template #header><th>delete></th></ng-template>
 <ng-template #content><button>delete></button></ng-template>
</table>
  

Я хочу упростить это до:

 <table>
  <!-- Row 1 -->
  <custom-column>
    <th header>edit></th>
    <button>edit></button>
  </custom-column>

  <!-- Row 2 -->
  <custom-column>
    <th header>delete></th>
    <button>delete></button>
  </custom-column>
</table>
  

У меня почти получилось это в этом стекблите


Проблема

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что мне нужно повторить шаблон содержимого для каждой строки в таблице, чтобы для каждой строки была кнопка редактирования и удаления. Но при такой настройке кнопки отображаются только в последней строке (я думаю, это потому, что ng-content только один раз переходит?).

Возможно ли то, чего я пытаюсь достичь, и если да, то как мне следует изменить свой код?

Комментарии:

1. На самом деле он преобразуется для каждой итерации (как вы можете видеть комментарии к привязке), но он проецируется только на последнюю итерацию.

Ответ №1:

Поскольку ng-content компонент не поддерживает многократное проецирование одного и того же содержимого (здесь и здесь) Мне нужно было переключиться на внедрение шаблонов в компонент таблицы.

Вдохновленный тем, как Primeng решает эту проблему (путем создания директивы, которая содержит шаблон):

 @Directive({ selector: '[pTemplate]' })
export class PrimeTemplate {

  @Input() type: string;

  @Input('pTemplate') name: string;

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

  getType(): string {
    return this.name;
  }
}
  

Использование: <ng-template pTemplate="header"></ng-template

Они создают шаблон и получают ссылку на этот шаблон в компоненте таблицы. Шаблон можно использовать неограниченное количество раз, что решает проблему проекции.


Поскольку я хотел сохранить гибкость, но хотел избежать использования сравнения строк (обратите внимание на свойство ‘name’) и необходимость извлечения правильных шаблонов из querylist , я закончил созданием 2 директив, которые можно использовать следующим образом (примерно так же, как, например, моя первая попытка, но лучшая реализация):

 <ng-container>
  <ng-template appColHeader>Delete</ng-template>
  <ng-template appColContent><button>Not here!</button></ng-template>
</ng-container> 
  

Полная реализация этого кода может быть найдена в этом StackBlitz.