Home > Net >  Bind checkbox value to parent component with controlvalueaccesor
Bind checkbox value to parent component with controlvalueaccesor

Time:11-01

I recently started learning Angular and I'm facing a form issue. I currently have a form with a label and an input field. Since this is quite a large form I decided to make a separate component for the input and validation of the form.

A table row therefore looks like this:

          <tr
            app-table-row-input
            [label]="'ConfigInterval'"
            [formControl]="RestForm.controls['ConfigInterval']"
            [type]="'number'"
          ></tr>

HTML table-row-input

    <th>
    <label >{{ label }}</label>
    </th>
    <th>
    <input
    type="{{ type }}"
    [ngClass]="{
      'validation invalid': !ngControl.valid
    }"
    style="width: auto"
    
    [formControl]="ngControl.control"
    required
    />
    <span
    
    *ngIf="ngControl.invalid && (ngControl.dirty || ngControl.touched)"
    >
    Not valid
    </span>
    </th>

The types of number and text result in the form input being updated. However when I try to also use this for the checkbox type the form isn't updated with "true" or "false" like it does when not using a separate component. My code for the checkbox currently looks like this:

html parent Form component

            <tr
            app-table-checkbox
            [label]="'AuthEnabled'"
            [formControl]="RestForm.controls['AuthEnabled']"
            [id]="'cb1'"
            [type]="'checkbox'"
            ></tr>

html checkbox input component:

    <th>
     <label >{{ label }}</label>
    </th>
    <th>
    <input
    type="{{ type }}"
    
    id="{{ id }}"
    [formControl]="ngControl.control"
    required
    />
    <label for="{{ id }}">True or False</label>
    </th>

The TS in both components looks the same (except for id property not being there):

    export class TableCheckboxComponent implements ControlValueAccessor {
   @Input() label: string;
   @Input() type = 'text';
   @Input() id: string;

   constructor(@Self() public ngControl: NgControl) {
    ngControl.valueAccessor = this;
   }
   writeValue(obj: any): void {}
   registerOnChange(fn: any): void {}
   registerOnTouched(fn: any): void {}
   }

Can somebody explain why the text and number inputs do work but this doesnt work for the checkbox?

CodePudding user response:

type="{{ type }}" is initially resolving as type="text" and only type="checkbox" after inputs are bound and this is messing up ngControl.valueAccessor = this;.

The constructor runs prior to when the inputs are bound in the component lifecycle.

Suggest removing type input from TableCheckboxComponent and putting type="checkbox" directly on the input.

Stackblitz

  • Related