简体   繁体   中英

Angular reactive form - checkboxes - Initialize formArray with exisitng array

I have an dynamic array of lkBoardTypeList list fetched from server. I want to push that array to form array on initialization, basically i want to show checkboxes based on Board name or id in array. I know how to push an empty array in reactive forms.but how to initialize with an existing array.Actually its an update/edit Component

export class BoardTypeList{
id number;
descr string;
}

component:

lkBoardTypeList: LkBoardType[] = []; 
SelectedLkBoardTypeList: LkBoardType[] = []; 

this.boardDashboardForm = this.formBuilder.group({
                    id: new FormControl(this.boardObj.id, Validators.required),
                    location: new FormControl(this.boardObj.location),
                    boardType: new FormArray([])
                 });
this.addCheckBoxes();

..//..//

 addCheckBoxes(){
        this.lkBoardTypeList.forEach(() => this.boardTypeFormArray.push(new FormControl(false)));
    }

 get boardTypeFormArray(){ 
        return this.boardDashboardForm.controls.boardType as FormArray;
    }

loadSelected(event){
    
        this.boardService.getBoardTypeById(event.value).subscribe( posts =>{
            this.data = posts; 
            console.log('getBoardTypeById',this.data);
            },
            error => { 
            console.log('getBoardTypeById - error',error);
            this._errorService.handleError(error); 
            }, 
            () => {   
            this.SelectedLkBoardTypeList = this.data.boardTypes;
            for (let i = 0; i < this.lkBoardTypeList.length; i++) {
            ..///.. what code goes here
            }
            }); 
}

And in the HTML

<div class="row">
                
                <div class="col-sm-2">                
                    <p-dropdown [options]="boardArray" formControlName="id"  (onChange)="loadSelected($event)" placeholder=" Select "></p-dropdown> 
                </div>
                
            </div>
    <div class="form-group" >
                        <div formArrayName="boardType" *ngFor="let c of boardTypeFormArray.controls; let i = index">
                            <input class="col-sm-1" type="checkbox" [formGroupName]="i"/>
                            <span class="col-sm-5" >{{lkBoardTypeList[i].descr}}</span>
                        </div>
                    </div>

RightNow when I inspect element I see formArrayName="boardType" and checkbox element as follows:

<input class="col-sm-1 ng-untouched ng-pristine ng-valid" type="checkbox" ng-reflect-name="0">
<input class="col-sm-1 ng-untouched ng-pristine ng-valid" type="checkbox" ng-reflect-name="1">
<input class="col-sm-1 ng-untouched ng-pristine ng-valid" type="checkbox" ng-reflect-name="2">

I am guessing the ng-reflect-name="0" is nothing but value of 'i'. What am trying to set value of the array with id from lkBoardTypeList which is 10,20,30.

Also please let me know how to set the values for checked in the checkboxes. SelectedLkBoardTypeList - say for example the entire list has values (10,20,30). selectedList contains only 10 and it has to be checked.

First of all, you should use [formControlName]="i" instead of [formGroupName]="i"

ng-reflect-${name} attribute is added for debugging purposes and shows the input bindings that a component/directive has declared in its class.

FormControlName directive declares

@Input('formControlName') name!: string|number|null;

So, you're right: ng-reflect-name="0" describes value you're passing in formControlName input.


If you want to prepopulate FormArray with SelectedLkBoardTypeList then you can just check if specific item exists in SelectedLkBoardTypeList . Let's say you have:

SelectedLkBoardTypeList: LkBoardType[] = [
  {
    id: 10,
    descr: 'Type 1'
  }
];

then your addCheckBoxes method should be as follows:

addCheckBoxes() {
  this.lkBoardTypeList.forEach((type) => {
    const selected = this.SelectedLkBoardTypeList.some(x => x.id === type.id);
    this.boardTypeFormArray.push(new FormControl(selected))
  });
}

Finally, if you want to get selected items during post execution you can map selected values in FormArray to your original array:

save() {
  const model = this.boardDashboardForm.value;

  const selectedTypes = model.boardType.filter(Boolean).map((_, i) => this.lkBoardTypeList[i]);
  console.log(selectedTypes);
}

Ng-run Example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM