Потужність селекторів в Angular: пояснення на практичному прикладі

353

Від автора: вашій увазі пропонується стаття, присвячена вивченню фреймворку AngularJS. При роботі зі сторонніми компонентами буває потрібно підключити відсутній функціонал. Наведемо Angular приклад — для цього візьмемо компонент кастомный чекбокс.

Потужність селекторів в Angular: пояснення на практичному прикладі

@Component({
selector: ‘ngx-checkbox’,
template: `
{{label}}
`,
})
export class CustomCheckboxComponent {
@Input() label;
}

Вам потрібен цей компонент, але біда в тому, що він не підтримує доступність.

Змінювати код ви точно не будете, тоді як обійти цю проблему за допомогою Angular?

«Нам доступна вся міць селекторів.»

Ми можемо створити директиву, яка буде посилатися на цей input по класу, після чого з допомогою Angular API можна додати все, що завгодно. (підтримувані типи селекторів можна знайти за посиланням).

@Directive({
selector: ‘.ngx-checkbox’
})
export class CustomCheckboxAddonsDirective {
@HostBinding(‘attr.role’) role = ‘checkbox’;
@HostBinding(‘attr.aria-checked’) checked = false;
@HostBinding(‘attr.tabindex’) tabIndex = 0;
@HostListener(‘change’, [‘$event.target.checked’])
change( checked ) {
this.checked = checked;
}
}

Потужність селекторів в Angular: пояснення на практичному прикладі

Добре, але залишилася ще одна проблема. Angular в нашому додатку буде перевіряти прив’язки директиви для кожного циклу виявлення змін. В більшості випадків воно нам не потрібно, якщо, звичайно, у нас немає динамічних значень типу aria-checked.

Вирішити цю проблему можна за допомогою ChangeDetectorRef API.

@Directive({
selector: ‘ngx-checkbox input[type=”checkbox”]’
})
export class CustomCheckboxAddonsDirective {
@HostBinding(‘attr.role’) role = ‘checkbox’;
@HostBinding(‘attr.aria-checked’) checked = false;
@HostBinding(‘attr.tabindex’) tabIndex = ‘0’;
constructor( private cdr : ChangeDetectorRef ) {}
ngAfterViewInit() {
this.cdr.detach();
}
@HostListener(‘change’, [‘$event.target.checked’])
change( checked ) {
this.checked = checked;
this.cdr.detectChanges();
}
}

За допомогою методу detach() ми відокремлюємо детектор змін від дерева детектора змін. Відокремлений детектор змін не буде працювати, поки не буде виконаний метод reattached.

В нашому випадку ми можемо використовувати метод detectChanges() для виконання перевірок локальних змін тільки в динамічних частинах. (як aria-checked).