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>

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

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

Как добавить ng-bootstrap компоненты в проект Angular-CLI?

Покажу на примере нового проекта.

ng new project_name
cd project_name
npm install --save bootstrap@next
npm install --save @ng-bootstrap/ng-bootstrap

В angular-cli.json в секцию style надо добавить наш CSS, чтобы глобально подключить стили.

  "styles": [
    "styles.css",
    "../node_modules/bootstrap/dist/css/bootstrap.min.css"
  ],
17 августа 2017 г. в Angular

Angular environment variables

Создание и использования переменных окружения в Angular с использованием CLI >= 6 версии.

08 января 2019 г. в Angular

#local variable внутри *ngIf

Представлены 2 варианта решения, как сослаться на локальную переменную шаблона (#myVar) за пределами шаблона:

  • @ViewChild
  • @ViewChildren
13 февраля 2019 г. в Angular