По сути, я пытаюсь воспроизвести поведение электронной таблицы. У меня есть несколько реактивных форм, каждая из которых касается определенного раздела общего расчета. И одни исходные данные влияют на ценность других. Для упрощения возьмем этот пример.
Форма A содержит информацию о ссуде, включая процентную ставку. Форма B содержит банковскую информацию, включая платеж по ссуде. Форма C показывает итоговые суммы по различным категориям расходов (не только по кредитам). Когда ставка изменяется в A, мне нужно обновить платеж по кредиту в B, что обновит итоги в C.
Если бы это было все, я думаю, мое решение было бы простым. Однако загвоздка в том, что у меня есть служба для обработки общих вычислений. Каждая форма вычисляет свои собственные итоги и передает их в службу. Сервис производит «основной расчет» и исправляет реактивные формы.
Таким образом, форма A изменяется, вызывая событие «valueChanges», которое запускает основной расчет службы. Основной расчет обновляет итоги в C и поля в форме B. Теперь B необходимо пересчитать свои промежуточные итоги. Когда B завершит свои промежуточные итоги, необходимо снова запустить основной расчет службы для обновления C. Проницательный с вашей стороны уловит бесконечный цикл, который ждет впереди, если я не использую:
{ emitEvent: false }
с моим вызовом patchValues.
Я новичок в реактивных формах и концепции разделения формы и данных. Это легко сделать, когда в сервисе есть все поля, и я использую ngModel для ввода; поменять услугу, поменять форму.
Я надеюсь, что кто-то, кто является экспертом в этой парадигме разделения данных, прольет свет на то, как я могу достичь своей цели. При необходимости я бы принял совершенно новый подход. Идея, опять же, состоит в том, чтобы воспроизвести функциональность электронных таблиц с модульными разделами данных (позволяя банковской информации, расходам и итоговым данным сохранять свою автономность).
По запросу я добавил часть кода.
/* When any form changes, it updates the service
It then triggers the calculate function so that the relevant fields are
updated.
*/
/* Form A */
onFormChange() {
const formVals = this.loanForm.getRawValue(); // one of the values is the loan rate
this.calcSubTotals(); // adds up the relevant fields in each loan.
for(const formFieldKey of Object.keys(formVals)) {
this.calculationService[formFieldKey] = formVals[formFieldKey]
}
this.calculationService.calculate();
}
/* Form B */
onFormChange() {
const formVals = this.bankForm.getRawValue();
this.calcSubTotals(); // adds up the fields in each account. One of those fields is a loan payment that is updated by the service
for(const formFieldKey of Object.keys(formVals)) {
this.calculationService[formFieldKey] = formVals[formFieldKey]
}
this.calculationService.calculate();
}
/* Form C - Summary */
onFormChange() {
const formVals = this.summaryForm.getRawValue();
// I won't break this down as it doesn't have any calcuated values
// however, it does show allCosts which is updated by the calculation service
for (const formFieldKey of Object.keys(formVals)) {
this.calculationService[formFieldKey] = formVals[formFieldKey]
}
this.calculationService.calculate();
}
/* Calculation Service */
calculate() {
// Various calculations occcur here
// All calcuations use the values of the service...not the individual forms
// one of the values that is modified here is payment
const loanPayment = ...; // math here to get the loanPayment
const allCosts = ...; // this is the tricky part. I;m summing all of the subtotals
this.bankForm.patchValues({
loanPayment: calculatedLoanPayment // the other tricky part. loanPayment affects the subtotal which has already been used above
}, {emitEvent: false});
this.summaryForm.patchValues({
allCosts: calculatedAllCosts;
});
}