所以,当我遇到一些有趣的事情时,我只是在关注自己在Gitter上的生意。看一下this Stackblitz demo。
它使用一个自定义指令,使自定义复选框组件可以与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>