Angular - Почему нажатие на флажок запускает событие изменения для родительского селектора, с которым связано событие изменения? - PullRequest
0 голосов
/ 03 октября 2018

Итак, я просто занялся своим делом в Gitter, когда наткнулся на что-то интересное.Взгляните на эту демонстрацию Stackblitz .

Используется пользовательская директива, которая заставляет настраиваемый компонент-флажок работать с ngModel / formControl и т. Д.

Что я не понимаю, так это как события устанавливаются для hostв работе NgCheckboxControlDirective.Так как хост здесь является селектором для компонента-флажка, а не для самого входа флажка, он не должен вызывать любое событие change или blur, но это так.

Если вы установите флажокв демоверсии, связанной сверху, вы увидите, что choosen изменяется между true и false.

Почему?Почему нажатие на флажок вызывает здесь событие change, которое затем обновляет состояние choosen?

Директива, которая реализует ControlValueAccessor:

import { Directive, Renderer2, ElementRef } from '@angular/core';
import { ControlValueAccessor , NG_VALUE_ACCESSOR } from '@angular/forms';

@Directive({
  selector: '[ngCheckboxControl]',
  host: {'(change)': 'onChange($event.target.checked)', '(blur)': 'onTouched()'},
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: NgCheckboxControlDirective,
      multi: true
}
  ]
})
export class NgCheckboxControlDirective implements ControlValueAccessor {

  onChange = (_: any) => {};
  onTouched = () => {};

  constructor(private _renderer: Renderer2, private _elementRef: ElementRef) {}

  writeValue(value: any): void {
    this._renderer.setProperty(this._elementRef.nativeElement.firstElementChild, 'checked', value);
  }
  registerOnChange(fn: (_: any) => {}): void { this.onChange = fn; }
  registerOnTouched(fn: () => {}): void { this.onTouched = fn; }

  setDisabledState(isDisabled: boolean): void {
    this._renderer.setProperty(this._elementRef.nativeElement.firstElementChild, 'disabled', isDisabled);
  }
}

Флажок:

import { Component, ElementRef } from '@angular/core';
import { NgControl } from '@angular/forms';

@Component({
  selector: 'checkbox-layout',
  template: `
    My checkbox: <input type="checkbox" />
  `,
})
export class CkeckboxLayoutComponent {

  constructor(
    private ngControl: NgControl,
    private elementRef: ElementRef
  ) {
    console.log('... elementRef:', elementRef);
    console.log('... ngControl:', ngControl);
  }

}

Тогда вы будете использовать это так:

<checkbox-layout formControlName="choosen" ngCheckboxControl></checkbox-layout>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...