For a simple checkbox with a string value bound to a FormControl:
export class CheckboxComponent {
formControl: FormControl;
option: {value: string};
cons
I believe I solved your (and my) issue by utilizing a custom directive that "overrides" the default CheckboxControlValueAccessor. Angular2 core sets the onChange event to fire whether the box is checked or not. The code below fires an object with the whether it's checked and the value. You will just need to set the html element as an input of type checkbox, and attached the value you want to track with [value]={valueToTrack}
import {Directive, ElementRef, Renderer, forwardRef} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
export const CHECKBOX_VALUE_OVERRIDE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CheckboxControlValueOverrideAccessor),
multi: true,
};
@Directive({
selector: 'input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]',
host: {'(change)': 'onChange({checked: $event.target.checked, value: $event.target.value})', '(blur)': 'onTouched()'},
providers: [CHECKBOX_VALUE_OVERRIDE_ACCESSOR]
})
export class CheckboxControlValueOverrideAccessor implements ControlValueAccessor {
onChange = (_: any) => {};
onTouched = () => {};
constructor(private _renderer: Renderer, private _elementRef: ElementRef) {}
writeValue(value: any): void {
this._renderer.setElementProperty(this._elementRef.nativeElement, 'checked', value.checked);
}
registerOnChange(fn: (_: any) => {}): void { this.onChange = fn; }
registerOnTouched(fn: () => {}): void { this.onTouched = fn; }
setDisabledState(isDisabled: boolean): void {
this._renderer.setElementProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
}
}