Angular. Изменение функциональности компонентов с помощью директив

На текущем проекте мы используем библиотеку компонентов от PrimeNG, и в ~20 местах повторяется следующий код для компонента календаря вида:

<p-calendar
    formControlName="begin"
    [minDate]="operationalPlanMinDate"
    [maxDate]="operationalPlanMaxDate"
    [showIcon]="true"
    [showTime]="true"
    [firstDayOfWeek]="1"
    [readonlyInput]="true"
    hourFormat="24"
    dateFormat="dd.mm.yy"
></p-calendar>

В статье Use Angular directives to extend components that you don't own приводится лаконичное решение с использованием директивы для настройки сторонних компонентов:

import { Directive } from '@angular/core';
import { Calendar } from 'primeng/calendar';

@Directive({
  selector: 'p-calendar[sopDatetimeCalendar]',
})
export class SopDatetimeCalendarDirective {
  constructor(private calendar: Calendar) {
    this.calendar.dateFormat = 'dd.mm.yy';
    this.calendar.firstDayOfWeek = 1;
    this.calendar.hourFormat = '24';
    this.calendar.readonlyInput = true;
    this.calendar.showIcon = false;
    this.calendar.showTime = true;
  }
}

В результате HTML шаблон упрощается:

<p-calendar
    formControlName="begin"
    [minDate]="operationalPlanMinDate"
    [maxDate]="operationalPlanMaxDate"
    sopDatetimeCalendar
    [showIcon]="true" <!-- можно переопределять -->
></p-calendar>

Вариант приминения для расширения ngFor

trackByKey директива, чтобы каждый раз не создавать функцию trackBy

import { NgForOf } from '@angular/common';
import { Directive, Input } from '@angular/core';

@Directive({ selector: '[ngFor]' })
export class NgForTrackByKeyDirective<T = any> {
  constructor(private ngForRef: NgForOf<T>) {}

  @Input()
  set ngForTrackByKey(key: keyof T) {
    if (key) {
      this.ngForRef.ngForTrackBy = (_index, item) => item[key];
    }
  }
}

Приминение

<div *ngFor="let item of list; trackByKey: 'id'">
  {{ item.id }} - {{ item.value }}
</div>

Посмотреть на результат:

Похожие записи

@Directive v/s @Component in Angular

Компоненты создают DOM элементы и добавляют к ним поведение, а директивы только добавляют поведение к существующим DOM элементам

13 августа 2018 г. в Angular

Вставить <script> в Angular компонент

Добавление сторонних скриптов в Angular по запросу. Как известно, добавить скрипт через шаблон невозможно. Представлено решение как это сделать программно.

15 ноября 2019 г. в Angular

Angular. Отличие baseHref от deployUrl

  • deployUrl - задаёт путь для статических (js, css) файлов в index.html.
  • baseHref - определяет base, используется в ссылках и маршрутизации (routing) Angular