angular2 checkbox formcontrol

2019-03-26 07:01发布

For a simple checkbox with a string value bound to a FormControl:

export class CheckboxComponent {
  formControl: FormControl;
  option: {value: string};

  constructor() {
    this.formControl = new FormControl(); 
    this.option = {value: "MyValue"};

         this.formControl.valueChanges.subscribe(console.log);
  }

}
<input type="checkbox" [formControl]="formControl" [value]="option.value" name="SomeName" />

The output of the subscribe is true, false, true, false.... I want the angular 2 to bind the string value "MyValue" in the FormControl.

By default angular 2, FormControl and checkboxes seem to bind boolean values which is strange since default browser submit behaviour is to send the value of the checkbox and, in the case of multiple checkboxes with the same name, an array of checkbox values bound to the name of the checkboxes.

Would be pretty useless to submit:

Items=[true, false, true, true, true, false]

Instead of:

Items=[Toothbrush, Floss, Glock, Clean underwear]

So in essence: How to make angular 2 bind the string value not the boolean value?

Kind regards,

1条回答
Explosion°爆炸
2楼-- · 2019-03-26 07:40

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);
  }
}
查看更多
登录 后发表回答