что вы хотите сделать, это добавить функцию, подпишитесь на valueChanges
задействованных элементов управления и используйте ее, чтобы установить желаемое значение элемента управления.
onAddRegisterDetail() {
this.billingRegisterArray = <FormArray>this.billingRegisterForm.get('registerDetails');
const grp = this.formBuilder.group({
id: [null],
quantity: [1, [Validators.required, Validators.min(1), Validators.min(1)]],
unitPrice: [0.00, [Validators.required, Validators.pattern(this.mobnumPattern)]],
enteredGrossAmount: [{ value: 0.00, disabled: true }, Validators.required],
discountRate: [0.00, Validators.required],
enteredDiscountAmount: [{ value: 0.00, disabled: true }, Validators.required],
enteredNetAmount: [{ value: 0.00, disabled: true }, Validators.required],
description1: [null, Validators.required],
flexFieldCombinationId: ['', Validators.required],
uomId: [null, Validators.required],
taxClassId: [null, Validators.required]
});
// get the controls
const quantityCtrl = grp.get('quantity');
const priceCtrl = grp.get('unitPrice');
const grossAmtCtrl = grp.get('enteredGrossAmount');
// combine value changes, start one with initial value
combineLatest(
quantityCtrl.valueChanges.pipe(startWith(quantityCtrl.value)),
priceCtrl.valueChanges.pipe(startWith(priceCtrl.value)) // may need to coerce type with map
).subscribe(([quantity, unitPrice]) => grossAmtCtrl.setValue(quantity * unitPrice)) // may need to format
this.billingRegisterArray.push(grp);
// you should only set the control and data source once
// this.billingRegisterForm.setControl('registerDetails', this.billingRegisterArray);
// this.dataSource = new MatTableDataSource((
this.billingRegisterForm.get('registerDetails') as FormArray).controls);
}
this должен быть безопасным и не вызывать утечек памяти, так как все локально и должен собирать мусор нормально, но если вы хотите быть в безопасности, добавьте некоторое свойство контроллера, например:
private grossAmtSubs: Subscription[] = []
и pu sh подписки на него :
this.grossAmtSubs.push(
combineLatest(
...
).subscribe( ... )
);
и добавьте хук ngOnDestroy
для отмены подписки.
ngOnDestroy() {
this.grossAmtSubs.forEach(s => s.unsubscribe())
}
это гарантирует отсутствие утечек памяти и является хорошей практикой, но должно быть безопасным в любом случае.
также, если у вас есть функция удаления элемента, вы также можете попытаться отписаться там ...
onDelete(i: index) {
const registerDetails = <FormArray>this.billingRegisterForm.get('registerDetails');
registerDetails.removeAt(i);
this.grossAmtSubs[i].unsubscribe();
this.grossAmtSubs.splice(i,1);
}
изменить ... если вы хотите суммировать, подписаться на изменения массива где-то, как ...
this.billingRegisterForm.get('registerDetails').valueChanges.pipe(
map(values => values.reduce((total, value) => total += value.enteredGrossAmount, 0)),
distinctUntilChanged()
).subscribe(total => console.log('do whatever with the total: ', total))