动态添加的元素在 Angular 中不可见
Dynamically added elements are not visible in Angular
我在 mat 对话框中使用 FormArray
表单。当我点击 (+) 按钮时,新的地址字段被添加,但在我点击它们之前它们是不可见的。
这是 class 形式
hide = true;
loginForm: FormGroup;
signInForm: FormGroup;
address: FormArray;
formisvalid = false;
emailRegx = /^(([^<>+()\[\]\.,;:\s@"-#$%&=]+(\.[^<>()\[\]\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,3}))$/;
@Output()
closeDialog = new EventEmitter<boolean>();
constructor(private formBuilder: FormBuilder, private userService: UserService,
private errorHandler: ErrorHandlingService, private successHandler: SuccessHandlerService) {
}
ngOnInit() {
this.signInForm = this.formBuilder.group({
firstname: [null, Validators.required],
lastname: [null, Validators.required],
email: [null, [Validators.required, Validators.pattern(this.emailRegx)]],
password: [null, Validators.required],
reEnterPassword: [null, Validators.required],
mobile: [null],
home: [null],
address: this.formBuilder.array([this.createAddress()])
});
}
createAddress(): FormGroup {
return this.formBuilder.group({
street1: [null],
street2: [null],
city: [null]
})
}
addAddress(): void {
this.address = this.signInForm.get('address') as FormArray;
this.address.push(this.createAddress());
}
这是数组形式的部分
<td colspan="2">
<div class ="divL">
<div formArrayName="address" *ngFor="let address of signInForm.get('address')['controls']; let i = index;">
<form formGroupName="i">
<table>
<tr>
<td>
<mat-form-field class="form-field" appearance="outline">
<mat-label>Street 1</mat-label>
<input formControlName="street1" matInput />
</mat-form-field>
</td>
<td>
<mat-form-field class="form-field" appearance="outline">
<mat-label>Street 2</mat-label>
<input formControlName="street2" matInput />
</mat-form-field>
</td>
</tr>
<tr>
<td>
<mat-form-field class="form-field" appearance="outline">
<mat-label>City</mat-label>
<input formControlName="city" matInput />
</mat-form-field>
</td>
</tr>
</table>
</form>
</div>
</div>
<div class="divR">
<button mat-icon-button type="button" (click)="addAddress()">
<mat-icon aria-hidden="true" class="plus-icon">add_circle_outline</mat-icon>
</button>
</div>
</td>
当我单击其中一个不可见字段时,它会变为可见
为什么会这样?如何解决?
我认为这里没有触发角度变化检测。基本上 *ngFor 不会重新评估,因为它不知道数组已更改。
您可以尝试通过更改添加函数中的数组引用来解决此问题
this.address = [...this.address];
另一种解决方案可能是通过 https://angular.io/api/core/ChangeDetectorRef#detectchanges
显式触发更改检测
由于您使用的 formGroup 索引数组是动态值。所以我们需要使用 属性 绑定 formGroupName 以与父表单同步
按如下方式更改您的代码:
formGroupName="i"====>[formGroupName]="i"
<td colspan="2">
<div class ="divL">
<div formArrayName="address" *ngFor="let address of signInForm.get('address')['controls']; let i = index;">
<form [formGroupName]="i">
<table>
<tr>
<td>
<mat-form-field class="form-field" appearance="outline">
<mat-label>Street 1</mat-label>
<input formControlName="street1" matInput />
</mat-form-field>
</td>
<td>
<mat-form-field class="form-field" appearance="outline">
<mat-label>Street 2</mat-label>
<input formControlName="street2" matInput />
</mat-form-field>
</td>
</tr>
<tr>
<td>
<mat-form-field class="form-field" appearance="outline">
<mat-label>City</mat-label>
<input formControlName="city" matInput />
</mat-form-field>
</td>
</tr>
</table>
</form>
</div>
</div>
<div class="divR">
<button mat-icon-button type="button" (click)="addAddress()">
<mat-icon aria-hidden="true" class="plus-icon">add_circle_outline</mat-icon>
</button>
</div>
</td>
FormGroupName
accepts the string name of the nested FormGroup to link, and looks for a FormGroup registered with that name in the parent FormGroup instance you passed into FormGroupDirective
.
但是,当我们动态地将项目索引用作 FormGroupName 时,我们需要通过两种类型将值传递给该指令。
formGroupName="{{i}}"
[formGroupName]="i"
您尝试过的方法 formGroupName="i"
其中 i
索引始终未定义未同步值,这是您代码的罪魁祸首。
希望这能解决您的问题。
我在 mat 对话框中使用 FormArray
表单。当我点击 (+) 按钮时,新的地址字段被添加,但在我点击它们之前它们是不可见的。
这是 class 形式
hide = true;
loginForm: FormGroup;
signInForm: FormGroup;
address: FormArray;
formisvalid = false;
emailRegx = /^(([^<>+()\[\]\.,;:\s@"-#$%&=]+(\.[^<>()\[\]\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,3}))$/;
@Output()
closeDialog = new EventEmitter<boolean>();
constructor(private formBuilder: FormBuilder, private userService: UserService,
private errorHandler: ErrorHandlingService, private successHandler: SuccessHandlerService) {
}
ngOnInit() {
this.signInForm = this.formBuilder.group({
firstname: [null, Validators.required],
lastname: [null, Validators.required],
email: [null, [Validators.required, Validators.pattern(this.emailRegx)]],
password: [null, Validators.required],
reEnterPassword: [null, Validators.required],
mobile: [null],
home: [null],
address: this.formBuilder.array([this.createAddress()])
});
}
createAddress(): FormGroup {
return this.formBuilder.group({
street1: [null],
street2: [null],
city: [null]
})
}
addAddress(): void {
this.address = this.signInForm.get('address') as FormArray;
this.address.push(this.createAddress());
}
这是数组形式的部分
<td colspan="2">
<div class ="divL">
<div formArrayName="address" *ngFor="let address of signInForm.get('address')['controls']; let i = index;">
<form formGroupName="i">
<table>
<tr>
<td>
<mat-form-field class="form-field" appearance="outline">
<mat-label>Street 1</mat-label>
<input formControlName="street1" matInput />
</mat-form-field>
</td>
<td>
<mat-form-field class="form-field" appearance="outline">
<mat-label>Street 2</mat-label>
<input formControlName="street2" matInput />
</mat-form-field>
</td>
</tr>
<tr>
<td>
<mat-form-field class="form-field" appearance="outline">
<mat-label>City</mat-label>
<input formControlName="city" matInput />
</mat-form-field>
</td>
</tr>
</table>
</form>
</div>
</div>
<div class="divR">
<button mat-icon-button type="button" (click)="addAddress()">
<mat-icon aria-hidden="true" class="plus-icon">add_circle_outline</mat-icon>
</button>
</div>
</td>
当我单击其中一个不可见字段时,它会变为可见
为什么会这样?如何解决?
我认为这里没有触发角度变化检测。基本上 *ngFor 不会重新评估,因为它不知道数组已更改。
您可以尝试通过更改添加函数中的数组引用来解决此问题
this.address = [...this.address];
另一种解决方案可能是通过 https://angular.io/api/core/ChangeDetectorRef#detectchanges
显式触发更改检测由于您使用的 formGroup 索引数组是动态值。所以我们需要使用 属性 绑定 formGroupName 以与父表单同步
按如下方式更改您的代码:
formGroupName="i"====>[formGroupName]="i"
<td colspan="2">
<div class ="divL">
<div formArrayName="address" *ngFor="let address of signInForm.get('address')['controls']; let i = index;">
<form [formGroupName]="i">
<table>
<tr>
<td>
<mat-form-field class="form-field" appearance="outline">
<mat-label>Street 1</mat-label>
<input formControlName="street1" matInput />
</mat-form-field>
</td>
<td>
<mat-form-field class="form-field" appearance="outline">
<mat-label>Street 2</mat-label>
<input formControlName="street2" matInput />
</mat-form-field>
</td>
</tr>
<tr>
<td>
<mat-form-field class="form-field" appearance="outline">
<mat-label>City</mat-label>
<input formControlName="city" matInput />
</mat-form-field>
</td>
</tr>
</table>
</form>
</div>
</div>
<div class="divR">
<button mat-icon-button type="button" (click)="addAddress()">
<mat-icon aria-hidden="true" class="plus-icon">add_circle_outline</mat-icon>
</button>
</div>
</td>
FormGroupName
accepts the string name of the nested FormGroup to link, and looks for a FormGroup registered with that name in the parent FormGroup instance you passed into FormGroupDirective
.
但是,当我们动态地将项目索引用作 FormGroupName 时,我们需要通过两种类型将值传递给该指令。
formGroupName="{{i}}"
[formGroupName]="i"
您尝试过的方法 formGroupName="i"
其中 i
索引始终未定义未同步值,这是您代码的罪魁祸首。
希望这能解决您的问题。