От автора: вашему вниманию предлагается статья, посвященная изучению фреймворка AngularJS. При работе со сторонними компонентами бывает нужно подключить отсутствующий функционал. Приведем Angular пример — для этого возьмем компонент кастомный чекбокс.
1 2 3 4 5 6 7 8 9 |
@Component({ selector: 'ngx-checkbox', template: ` <input type="checkbox" class="ngx-checkbox"> {{label}} `, }) export class CustomCheckboxComponent { @Input() label; } |
Вам нужен этот компонент, но беда в том, что он не поддерживает доступность.
Менять код вы точно не будете, тогда как обойти эту проблему с помощью Angular?
«Нам доступна вся мощь селекторов.»
Мы можем создать директиву, которая будет ссылаться на этот input по классу, после чего с помощью Angular API можно добавить все что угодно. (поддерживаемые типы селекторов можно найти по ссылке).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@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 в нашем приложении будет проверять привязки директивы для каждого цикла обнаружения изменений. В большинстве случаев оно нам не нужно, если, конечно, у нас нет динамических значений типа aria-checked.
Решить эту проблему можно с помощью ChangeDetectorRef API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
@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).
Автор: Netanel Basal
Источник: //netbasal.com/
Редакция: Команда webformyself.