各位板上的大大好,小弟最近剛使用Angular的Control Value Accessor開發一些專案,對於Angualr的Reactive Forms中的FormArray的綁定遇到了一些問題。
我在父Component中給訂了初始值:
import { Component, OnInit } from '@angular/core';
import {
FormArray,
FormBuilder,
FormControl,
FormGroup,
} from '@angular/forms';
@Component({
selector: 'app-root',
template: `
<form [formGroup]="myForm">
<div class="form-group">
<label>Name Array: </label>
<app-my-sub-array-component
formControlName="nameArray"
></app-my-sub-array-component>
</div>
</form>
<p>Form value: {{ myForm.value | json }}</p>
`,
styleUrls: ['./app.component.css'],
})
export class AppComponent {
title = 'control-value-accessor';
myForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit(): void {
this.initFormGroup();
}
private initFormGroup(): void {
this.myForm = this.fb.group({
nameArray: new FormControl([{street: 'street1', city: 'city1'}])
});
}
}
將[{street: 'street1', city: 'city1'}]
透過CVA傳遞給子Component(app-my-sub-array-component),在子Component中也確實有收到,但是對於forms綁定的時候卻出了狀況
import { Component, OnInit, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, AbstractControl, FormGroup, FormBuilder, FormControl, FormArray } from '@angular/forms';
@Component({
selector: 'app-my-sub-array-component',
template: `
<form [formGroup]="formGroup">
<ng-container formArrayName="addressList">
<ng-container *ngFor="let item of addressList.controls"; let i = index; [formGroupName]="i">
<label>Street: </label>
<input [formControlName]="street" type="text"/>
<label>City: </label>
<input [formControlName]="city" type="text"/>
</ng-container>
</ng-container>
</form>
`,
styleUrls: ['./my-sub-array-component.component.css'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MySubArrayComponentComponent),
multi: true
}
]
})
export class MySubArrayComponentComponent implements ControlValueAccessor {
formGroup: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.formGroup = this.fb.group({
addressList: this.fb.array([])
});
}
get addressList() {
return this.formGroup.get('addressList') as FormArray;
}
writeValue(value): void {
const addressList = this.formGroup.get('addressList') as FormArray;
if (value !== undefined && Array.isArray(value)) {
value.forEach(item => {
addressList.push(this.fb.group({
street: new FormControl(item.street),
city: new FormControl(item.city)
}));
});
}
}
registerOnChange(fn: (_: any) => void): void{
this.formGroup.valueChanges.subscribe(fn);
}
registerOnTouched(fn: (_: any) => void): void{
}
}
不知道是綁定的方式出了問題,一直無法將畫面中的input綁定到forms中,希望各位大大可以給我一點方向,謝謝各位。
我最近也在學習Angular, 應該可以交流一下
例如: [formControlName]="street" 和 formControlName="street" 的分別
前者Angular 會找class裏的 street 數值, 而class裏沒有定義street 因此會變成 formControlName="null"
後者則是直接給"street"的 value
Code
<form [formGroup]="formGroup">
<ng-container formArrayName="addressList">
<ng-container *ngFor="let item of addressList.controls; let i = index" [formGroupName]="i">
<label>Street: </label>
<input formControlName="street" type="text"/>
<label>City: </label>
<input formControlName="city" type="text"/>
</ng-container>
</ng-container>
</form>
沒錯,差不多就是樓上說的原因。
let index那邊怪怪的。
不過這裡會報錯的原因應該是formControlName綁定的是FormGroup裡面的key。
所以它應該要是字串,但你用了屬性綁定,你並沒有宣告該屬性的變數在FormArray下面,所以出錯。
把那邊的[]拿掉試試吧!
<ng-container *ngFor="let item of addressList.controls; let i = index" [formGroupName]="i">
<label>Street: </label>
<input formControlName="street" type="text" />
<label>City: </label>
<input formControlName="city" type="text" />
</ng-container>