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

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

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

Вступление

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

Например, для обработки столбцов имени и фамилии пользователя вам потребуется как минимум определить следующий HTML-код.

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

Было бы неплохо, если бы мы могли указать таблице отображать имя без явного определения этого столбца в HTML.

Создать столбцы

Для работы mat-table требуется matColumnDef для визуализации столбца. Мы можем сгенерировать определение этих столбцов в цикле. Итак, нам нужно получить список динамических столбцов, а затем выполнить цикл для генерации определений столбцов. Если мы установим имя нашего столбца как свойство нашей сущности, мы сможем просто получить доступ к свойству объекта из имени столбца.

Давайте посмотрим на это в действии.

Вот наш пользовательский интерфейс:

export interface User {
  firstname: string;
  lastname: string;
  mail: string;
  job: string;
}

Мы хотим автоматически генерировать столбцы имени и фамилии, вот как мы можем это сделать.

источник данных и столбцы вводятся для определения того, какие данные и какие столбцы необходимо отображать (см. часть 1). Здесь источник данных - это простой список пользователей. Мы определяем ввод столбцов следующим образом, чтобы отображать все столбцы.

columns: string[] = ['firstname', 'lastname', 'mail', 'job'];

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

dynamicColumns: string[] = ['firstname', 'lastname'];

Важная часть находится под комментарием Динамические столбцы (в HTML).

<ng-container *ngFor="let dynamicColumn of dynamicColumns" [matColumnDef]="dynamicColumn">

Эта строка проходит по динамическим столбцам и создает все matColumnDef для этих столбцов. Эта таблица сообщает mat-table о существовании столбцов firstname и lastname.

Затем нам нужно определить шаблон для заголовка и ячеек.

В заголовке столбца мы просто отображаем имя свойства (то есть имя или фамилию).

<mat-header-cell *matHeaderCellDef>      
   <p class="text-capitalize-first">{{dynamicColumn}}</p>    
</mat-header-cell>

В ячейках мы получаем имя или фамилию пользователя с именем столбца.

<mat-cell *matCellDef="let user">        
   <span>{{user[dynamicColumn]}}</span>    
</mat-cell>

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

И вуаля ! 🍾 Столбцы имени и фамилии теперь генерируются динамически, и вы можете просто добавить новые столбцы.

Начало хорошее, но мы можем его улучшить, есть некоторые проблемы:

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

Давай сделаем это !

Улучшения

Вычислить динамические столбцы

Чтобы вычислить динамические столбцы, мы можем получить их, проверив статические столбцы.

В нашем примере нашими статическими столбцами являются почта и работа (они задаются вручную в HTML).

staticColumns = ['mail', 'job']

Когда мы получаем список отображаемых столбцов, мы можем сравнить их со списком статических столбцов, чтобы получить список динамических столбцов.

Вот простая функция, которая сделает всю работу.

Теперь мы можем установить атрибут dynamicColumns компонента DynamicColumnsComponent со значением, возвращаемым этой функцией. В нашем примере эта функция вернет имя и фамилию, поскольку их нет в массиве staticColumns.

Улучшить набор текста

Чтобы улучшить набор текста, мы можем просто использовать клавишу типа. Мы определим тип для отображения всех статических столбцов (потому что мы больше не определяем список динамических столбцов) и столбцов для отображения.

Давайте создадим тип TableColumn.

export type TableColumn<T> = keyof T | string;

Мы делаем его универсальным для работы с любыми классами или интерфейсами.

Мы добавили строку объединения (| string), потому что в некоторых случаях статический столбец не является атрибутом объекта. Например, у вас может быть кнопка действия (например, для редактирования пользователя) в вашей таблице. Имя столбца будет «действие» и не является собственностью пользователя.

В основном этот тип помогает с автозаполнением, но он также позволяет разработчику определять любые статические столбцы (они не обязательно должны быть собственностью пользователя).

Создать абстрактный класс

Вот абстрактный класс, который

  • определить источник данных и столбцы
  • вычислить динамические столбцы при изменении отображаемых столбцов
  • использует тип TableColumn

Этот класс можно легко повторно использовать в другом компоненте таблицы.

И это последняя версия динамических столбцов, где дочерний компонент определяет только шаблон и список статических столбцов.

Список статических столбцов должен соответствовать столбцам, определенным в HTML, иначе таблица матов выдаст некоторую ошибку (например, повторяющиеся столбцы).

Вот рабочий пример с использованием финальной версии.



Возможные улучшения

Для расширенных динамических столбцов вы можете создать компонент, который обрабатывает различные типы объектов (например, строку, число, дату, Пользователь…) и использовать его в ячейке динамического столбца.

А для имени заголовка столбца вы можете использовать канал или объект карты, чтобы изменить имя столбца на другое.

Заключение

Вот как мне удалось сгенерировать динамические столбцы и уменьшить шаблонный код с помощью mat-table.

В части 3 мы увидим, как улучшить настройку, добавив в таблицу настраиваемые столбцы из родительского элемента.

Вот полный репозиторий серии на github. Эта часть - TableWithDynamicColumnsComponent → https://github.com/BobBDE/smart-mat-table

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