If you're coming from AngularJS (v1.x) you probably remember the ng-true-value
and ng-false-value
directive which allowed to map custom boolean values like "yes" or "no" or whatever other value you had, onto your HTML form. In this lesson we're going to implement our own trueFalseValue
directive for Angular, by directly hooking into Angular's form API. A nice occasion to learn about the ControlValueAccessor
interface.
import { Directive, Input, ElementRef, Renderer2, HostListener, forwardRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; @Directive({ selector: 'input[type=checkbox][trueFalseValue]', providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TrueFalseValueDirective), multi: true } ] }) export class TrueFalseValueDirective implements ControlValueAccessor { @Input() trueValue = true; @Input() falseValue = false; private propagateChange = (_: any) => { }; constructor(private elementRef: ElementRef, private renderer: Renderer2) { } @HostListener('change', ['$event']) onHostChange(ev) { this.propagateChange(ev.target.checked ? this.trueValue : this.falseValue); } writeValue(obj: any): void { // model -> view if (obj === this.trueValue) { // this.elementRef.nativeElement.checked = true; this.renderer.setProperty(this.elementRef.nativeElement, 'checked', true); } else { this.renderer.setProperty(this.elementRef.nativeElement, 'checked', false); } } registerOnChange(fn: any): void { this.propagateChange = fn; } registerOnTouched(fn: any): void { } setDisabledState?(isDisabled: boolean): void { } }
How to use:
<input type="checkbox" formControlName="lovingAngular" trueFalseValue trueValue="yes" falseValue="nope" > loving Angular?