Circular dependency of knockout computed

后端 未结 3 2026
日久生厌
日久生厌 2021-01-12 05:40

see working jsFiddle: http://jsfiddle.net/ruslans/vFK82/

I have 3 fields: Net Price (ex. tax), tax amount and Total price (price ex. vat + tax amount). the NetPrice

3条回答
  •  不思量自难忘°
    2021-01-12 06:09

    Some comments to the OP:

    • You don't need the return clause in the write method of the ko.computed.
    • Your approach uses the Number() function on several places and you might like to change that in order to get an specific precision (or some centralized place for validation of user input). So you can use ko.extenders to improve that. And I would specifically recommend the extender already made by the ko team named ko.extenders.numeric.
    • Your approach also uses console.log() on several places, and you might want to use another ko.extender made by the ko team ko.extenders.logChange.
    • Instead of a ko.computed in this case I think it's better to use subscribe as it will take less code (and probably insignificantly faster).

    My approach would be this:

    function viewModel() {
        this.TaxRate = 0.2;
        this.NetPrice = ko.observable().extend({ numeric: 2, logChange: "NetPrice"  });
        this.TaxAmt = ko.observable().extend({ numeric: 2, logChange: "TaxAmt"  });
        this.Total = ko.observable().extend({ numeric: 2, logChange: "Total"  });
    
        this.NetPrice.subscribe(function (newNetPrice) {
            this.TaxAmt(newNetPrice * this.TaxRate);
            this.Total(newNetPrice + this.TaxAmt());
        }, this);
        this.Total.subscribe(function (newTotal) {
            this.TaxAmt(newTotal - newTotal / (1 + this.TaxRate));
            this.NetPrice(newTotal - this.TaxAmt());
        }, this);
    
        this.NetPrice(100);
    }
    
    // then I have the extenders code copied exactly as seen in: http://knockoutjs.com/documentation/extenders.html)
    ko.extenders.numeric = ...
    ko.extenders.logChange = ... 
    
    // and finally init everything as usual
    ko.applyBindings(new viewModel());
    

    You can see the working fiddle here: http://jsfiddle.net/protron/JFPgu/2/

    Note how the numbers in this solution never have more decimals than the specified on the numeric extenders (even the value entered by the user is automatically fixed to the desired precision).

    And comparing my answer to the currently accepted answer by gaurav (which is also pretty nice and simple): I think the main advantage of my approach is that it'll let you use these awesome extenders.

提交回复
热议问题