mardi 13 juin 2017

Angular 2 - Custom Checkbox Component - Template-Driven Form Validation Not Working

I'm struggeling building a custom checkbox component that is being validated within a standard form (actually nothing special about it).

First, I started with a default implementation with 'required' attribute.

The following is working. The form is being validated correctly, the model value updates (true|false) and the submit button enables/disables:

<form (ngSubmit)="onSubmit()" #myForm="ngForm">
    // variable 'checkboxValue' comes from controller
    <input [(ngModel)]="checkboxValue" name="myCheckbox" id="myCheckbox" type="checkbox" required />
    <button type="submit" [disabled]="myForm.invalid">Submit</button>
</form>

Output:  // fine: outputs true || false

Next, I wanted to wrap my input field within an own component making use of Angular's ControlValueAccessor pattern.

checkbox.ts

@Component({
    selector: "bk-checkbox",
    template: `
        <input [(ngModel)]="value" [attr.name]="name" [attr.id]="name" type="checkbox" required/>
    `,
    providers: [
        { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => BkCheckbox), multi: true }
    ]
})
export class BkCheckbox implements ControlValueAccessor {
    @Input("name") name: string;
    private _innerValue: any;

    onChangeCallback: any = (_: any) => {};
    onTouchedCallback: any = () => {};

    get value(): any {
        return this._innerValue;
    };

    set value(value: any) {
        if (value !== this._innerValue) {
            this._innerValue = value;
            this.onChangeCallback(value);
        }
    }

    writeValue(value: any): void {
        if (value !== this._innerValue) {
            this._innerValue = value;
        }
    }

    registerOnChange(fn: (_: any) => {}): void { this.onChangeCallback = fn; }
    registerOnTouched(fn: () => {}): void { this.onTouchedCallback = fn; }
}

form-template.html

<form (ngSubmit)="onSubmit()" #myForm="ngForm">
    // variable 'checkboxValue' comes from controller
    <bk-checkbox name="myCheckbox2" [(ngModel)]="checkboxValue"></bk-checkbox>
    <button type="submit" [disabled]="myForm.invalid">Submit</button>
</form>

Output:  // BAD: outputs always true

Unfortunately, this does not work anymore. The model 'checkboxValue' updates correctly again (true|false) but my form always stays VALID even if unchecking the checkbox. :(

Can anybody help? <3




Aucun commentaire:

Enregistrer un commentaire