多种Angular反应形式和一项依赖于它们的服务

时间:2019-06-26 02:58:06

标签: angular angular-reactive-forms

我实质上是在尝试复制电子表格的行为。我有几种反应形式,每种形式都涉及整体计算的特定部分。有些投入会影响其他投入的价值。为简化起见,请以以下示例为例。

表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;
    });
}

1 个答案:

答案 0 :(得分:0)

我通过简单地将每个模块的新值与旧值进行比较来解决此问题。如果值更改,则发出更改事件。如果没有,我不会。这很简单,但是我不确定这是否是最好的方法,因为我最终仍然会运行一些感觉没用的代码,但是它可以工作。

新的工作流程: *表格A更改-触发计算服务 * Calc服务重新计算并发出更改 *表格A,B和C通过将旧值与新值进行比较来进行响应   -案例A:A表格由calc服务更改:它发出更改并再次触发calc     〜Calc重新计算并发出变化     〜表格A,B和C再次响应,但现在没有变化。 (对于我来说,这是“无用的……或”额外的代码。     〜完   -情况B:未更改任何形式:     〜结束

这仅起作用,因为计算中没有循环引用。很好,因为电子表格也不允许这样做。