У меня есть 2 FormGroups
, orderForm
и parcelForm
на странице, и parcelForm
динамически генерируется в FormArray
. parcelForm
имеет FormControl
, как net_weight
, gross_weight
и OrderForm
имеет FormControl
, то есть total_net_weight
и total_gross_weight
. Я хочу связать два значения parcelForm
FormControl net_weight
и gross_weight
, чтобы каждый раз, когда пользователь динамически добавлял parcelForm
и вводил значения для FormControl
net_weight
и gross_weight
, он отражал total_net_weight
и total_gross_weight
FormControl orderForm
. Я пробовал функцию 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>