如何将值从一个formgroup实时传递到另一个formgroup,作为反应式表单中的双向数据绑定



我在一个页面中有两个FormGroupsorderFormparcelForm,而parcelForm是在FormArray中动态生成的。parcelFormnet_weightgross_weight一样具有FormControl,而OrderForm具有FormControl,即total_net_weighttotal_gross_weight。我想两个绑定parcelFormFormControlnet_weightgross_weight的值,这样每当用户动态添加parcelForm并输入FormControlnet_weightgross_weight的值时,它将反映orderFormtotal_net_weighttotal_gross_weightFormControl。我尝试过patchValue功能,如this.parcelForm.get('parcels').patchValue([iterator, 'net_weight'])this.parcelForm.get('parcels').get([iterator, 'net_weight']).value,但都没有成功。这是new-order.page.ts:

import { Component, OnInit } from '@angular/core';
import { Order } from 'src/app/models/order.model';
import { FormGroup, FormControl, Validators, FormArray } from '@angular/forms';
import { OrderService } from 'src/app/services/order.service';
import { NavController, ModalController, ActionSheetController } from '@ionic/angular';
import { ActivatedRoute } from '@angular/router';

@Component({
selector: 'app-new-order',
templateUrl: './new-order.page.html',
styleUrls: ['./new-order.page.scss'],
})
export class NewOrderPage implements OnInit {
@Output() formChange = new EventEmitter();
pageTitle: string;
orders: Order[];
order: Order;
orderForm: FormGroup;
parcelForm: FormGroup;
error;
number_of_parcel = 0;
total_net_weight = 0;
total_gross_weight= 0;
constructor(
private orderService: OrderService,
) { }
ngOnInit() {
this.getAllDestionation();
this.orderService.getAllOrders()
.subscribe(
data => this.orders = data
);
this.orderForm = new FormGroup({
number_of_parcel: new FormControl(null, {
updateOn: 'blur',
validators: [Validators.required, Validators.min(1)]
}),
total_net_weight: new FormControl(null, {
updateOn: 'blur',
validators: [Validators.required, Validators.min(1)]
}),
total_gross_weight: new FormControl(null, {
updateOn: 'blur',
validators: [Validators.required, Validators.min(1)]
})
});
this.parcelForm = new FormGroup({
parcels: new FormArray([])
});
this.formChange.emit(this.parcelForm);
}

onSubmit() {
this.mapFormValuesToOrderModel();
if (this.order.id) {
this.orderService.updateOrder(this.order).subscribe(
() => {
this.goBack();
},
(err: any) => this.error = err
);
} else {
this.orderService.createOrder(this.order).subscribe(
(data) => {
this.orders.push(data);
this.goBack();
},
(err: any) => this.error = err);
}
}


goBack(): void {
this.navController.navigateRoot('/members/menu/tabs/orders');
}
onClick() {
console.log(this.orderForm);
}

parcels(): FormArray {
return this.parcelForm.get('parcels') as FormArray;
}
newParcelFormGroup(): FormGroup {
return new FormGroup({
net_weight: new FormControl(null, {
updateOn: 'blur',
validators: [Validators.required, Validators.min(1)]
}),
gross_weight: new FormControl(null, {
updateOn: 'blur',
validators: [Validators.required, Validators.min(1)]
}),
});
}
addParcelButtonClick() {
this.parcels().push(this.newParcelFormGroup());
this.number_of_parcel++;
let num = [];
let iterator = 0;
for (iterator = 0; iterator < this.number_of_parcel; iterator++) {
console.log(this.parcelForm.get('parcels').get([iterator, 'net_weight']).valueChanges);
num.push(Number(this.parcelForm.get('parcels').get([iterator, 'net_weight']).value));
}
console.log(num);
}
removeParcel(parcelIndex: number) {
this.parcels().removeAt(parcelIndex);
this.number_of_parcel--;
}
onChanges(): void {
console.log('parcelForm > onChanges', this.parcelForm.value);
this.parcelForm.valueChanges.subscribe(value => {
this.formChange.emit(this.parcelForm);
});
}
}

这是new-order.page.html:

<ion-header>
<ion-toolbar color="dark">
<ion-title>{{pageTitle}}</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-row>
<ion-col size-md="8" offset-md="2">
<form [formGroup]="orderForm">        
<ion-item *ngIf="hideTemplate">
<ion-label position="fixed">No. of Parcels</ion-label>
<ion-input type="text" autofocus formControlName="number_of_parcel">{{number_of_parcel}}</ion-input>
</ion-item>
<ion-label
*ngIf="orderForm.get('number_of_parcel').hasError('required') && orderForm.get('number_of_parcel').touched">
Name can't be empty!
</ion-label>
<ion-item>
<ion-label position="fixed">Total Net Weight</ion-label>
<ion-input type="text" autofocus formControlName="total_net_weight">{{total_net_weight}}</ion-input>
</ion-item>
<ion-label
*ngIf="orderForm.get('total_net_weight').hasError('required') && orderForm.get('total_net_weight').touched">
Name can't be empty!
</ion-label>
<ion-item>
<ion-label position="fixed">Total Gross Weight</ion-label>
<ion-input type="text" autofocus formControlName="total_gross_weight"></ion-input>
</ion-item>
<ion-label
*ngIf="orderForm.get('total_gross_weight').hasError('required') && orderForm.get('total_gross_weight').touched">
Name can't be empty!
</ion-label>
</form>
<br>
<br>
<ion-row>
<ion-col size="4" offset="10">
<ion-button color="success" (click)="addParcelButtonClick()">
<ion-icon name="add-outline"></ion-icon>Add Parcel
</ion-button>
</ion-col>
</ion-row>
<form [formGroup]="parcelForm">
<div formArrayName="parcels">
<div *ngFor="let parcel of parcels().controls; index as parcelIndex;">
<div [formGroupName]="parcelIndex">
Parcel {{parcelIndex + 1}}:
<ion-item>
<ion-label position="floating">Net Weight</ion-label>
<ion-input type="text" formControlName="net_weight"></ion-input>
</ion-item>
<ion-label *ngIf="parcel.get('net_weight').hasError('required') && parcel.get('net_weight').touched">
Remarks can't be empty!
</ion-label>
<ion-item>
<ion-label position="floating">Gross Weight</ion-label>
<ion-input type="text" formControlName="gross_weight"></ion-input>
</ion-item>
<ion-label *ngIf="parcel.get('gross_weight').hasError('required') && parcel.get('gross_weight').touched">
Remarks can't be empty!
</ion-label>
<br>
<ion-row>
<ion-col size="4" offset="10">
<ion-button color="danger" (click)="removeParcel(parcelIndex)">Remove <ion-icon name="trash-outline">
</ion-icon>
</ion-button>
</ion-col>
</ion-row>
</div>
</div>
</div>
</form>

</ion-col>
</ion-row>
</ion-content>

我能够通过以下方式获得值:

this.parcelForm.get('parcels').get([this.iterator, 'net_weight']).valueChanges.subscribe(
data => this.total_net_weight += data
);

我不需要在前端做任何更改。

这是我的addParcelButtonClick()函数最终看起来像

async addParcelButtonClick() {
this.parcels().push(this.newParcelFormGroup());
this.iterator = this.number_of_parcel;
let gross_weight = 0;
this.parcelForm.get('parcels').get([this.iterator, 'net_weight']).valueChanges.subscribe(
data => this.total_net_weight += data
);
this.parcelForm.get('parcels').get([this.iterator, 'gross_weight']).valueChanges.subscribe(
data => {
this.total_gross_weight += data;
gross_weight = data;
}
);

this.getOrderFormValues();
this.number_of_parcel++;
}

这是getOrderFormValues()函数:

getOrderFormValues() {
this.orderForm.setValue({
total_net_weight: this.total_net_weight,
total_gross_weight: this.total_gross_weight
});
}

这就是removeParcel函数:

async removeParcel(parcelIndex: number) {
// this.iterator = this.number_of_parcel;
if (this.parcelForm.get('parcels').get([parcelIndex, 'net_weight'])) {
this.total_net_weight -= await this.parcelForm.get('parcels').get([parcelIndex, 'net_weight']).value;
this.total_gross_weight -= await this.parcelForm.get('parcels').get([parcelIndex, 'gross_weight']).value;
}
this.parcels().removeAt(parcelIndex);
this.number_of_parcel--;
this.getOrderFormValues();
}

相关内容

最新更新