Это вторая статья из небольшой серии, целью которой является создание многоразовых и настраиваемых компонентов мат-стола при одновременном сокращении шаблонов.

В этой статье мы увидим, как мы можем сделать наш компонент mat-table более настраиваемым, предоставив возможность вставлять настраиваемый столбец.

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

Введение

Допустим, мы хотим отобразить таблицу пользователей (с именем, фамилией, почтой и должностью). Мы создадим UsersTableComponent, который будет содержать mat-table. Этот компонент принимает в качестве входных данных источник данных и список отображаемых столбцов. См. Часть 1 для более подробной информации о компоненте таблицы.

Этот компонент UsersTableComponent должен быть повторно использован в разных контекстах. Но предположим, что в административной части вы хотите отобразить список пользователей и хотите иметь возможность удалить пользователя. Вам понадобится столбец в таблице-мате с кнопкой для удаления пользователя.

Как было показано в части 1, мы не хотим, чтобы наш компонент UsersTableComponent был умным, и поэтому мы не хотим, чтобы он обрабатывал удаление пользователя, это ответственность родителя.

Мы могли бы определить столбец с кнопкой удаления и вызвать событие вывода при нажатии этой кнопки. Родитель получит это событие и удалит пользователя. Это хорошая идея, если кнопка удаления используется в приложении несколько раз.

Но мне не очень нравится это решение, потому что, если нам понадобится еще одна кнопка на другой странице (например, кнопка редактирования), нам придется определить один столбец и одно событие вывода для каждого конкретного действия. Наш компонент UsersTableComponent может быстро стать сложным (с множеством выходных событий и множеством конфигураций).

Ввести столбец

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

Если вас не устраивает проекция множественного контента в angular, вы можете проверить эту статью. Но в основном мы будем использовать тот же механизм, что и mat-table (для шаблонов заголовков и ячеек).

Решение довольно простое, воспользуемся TemplateRef.

Так что же здесь происходит?

В HTML мы определяем столбец с именем «customTemplate», это столбец, в который мы можем вставлять контент.

В заголовке столбца мы ничего не определяем, пока он нам не понадобится.

Важная часть находится в ячейке mat и в файле ts. В файле машинописного текста мы извлекаем шаблон, определенный родительским элементом, с помощью декоратора @ContentChild. Затем мы вводим этот шаблон в ячейку mat со следующей строкой:

<ng-container *ngTemplateOutlet="templateRef; context: getUserViewContext(user)"></ng-container>

Мы предоставляем контекст, чтобы шаблон мог получить доступ к пользователю.

Et voilà, теперь мы можем вводить контент в ячейку столбцов! 🍾

Вот как мы вызываем наш TableWithInjectableColumnComponent.

В файле ts мы определяем наш источник данных и список столбцов, которые мы хотим отобразить (нам нужно включить столбец «customTemplate», чтобы отобразить его в компоненте таблицы).

В HTML мы определяем нужный шаблон в столбце customTemplate, используя ‹ng-template›.

Мы используем let-user для доступа к пользователю, который был введен в контент с помощью TableWithInjectableColumnComponent.

Муравей, что это! Мы будем отображать этот шаблон в каждой ячейке customTemplate, а действие управляется нашим компонентом приложения (родительским) .

Вот рабочий пример на stackblitz.



Обратите внимание, что нам нужно вручную внедрить шаблон, и мы не можем напрямую использовать matColumnDef в родительском компоненте, потому что mat-table не сможет получить к нему доступ.

Улучшение

В этом примере у нас ничего не было в заголовке customTemplate. Мы могли бы установить простую строку ввода в компоненте таблицы, чтобы обеспечить заголовок. Если вы хотите иметь возможность полностью настраивать заголовок, вы также можете предоставить для него собственный шаблон. Вам нужно будет использовать директиву, чтобы различать заголовок и шаблон ячейки. Вы можете узнать, как это сделать, в следующей статье: Несколько-контент-проекций в угловой форме.

Заключение

Вот как мы можем предоставить возможность внедрить настраиваемый шаблон в компонент таблицы.

Это была последняя часть серии о mat-table, чтобы сделать их более многоразовыми, настраиваемыми при сокращении стандартного кода.

Я надеялся, что это помогло некоторым людям.

Спасибо за чтение :) !