knockout:不要在setter上评估计算的observable

时间:2014-03-07 20:14:50

标签: knockout.js deferred-execution

嗨我有以下功能。

function TaxModel() {
    this.amount = ko.observable("");
    this.percentage = ko.observable("");
    this.tax = ko.computed(
        {
            read:function() {
            return this.amount() * this.percentage();
        },
        deferEvaluation: true 
    }, this);
}

现在在onload期间,值应该将taxModel.tax设置为200.00(系统加载的值)。

我的HTML

<input type="text" data-bind="value: $data.amount, valueUpdate: 'afterkeydown'" id="amount"/>

<input type="text" data-bind="value: $data.percentage, valueUpdate: 'percentage'" id="percent"/>

<input type="text" id="tax" data-bind="value: $data.tax"/>

现在当我加载页面时,我想为observable设置最初的值,但我不希望在用户进行onchange之前计算该值。

var taxModel = new TaxModel();
taxModel.amount(100.00);
taxModel.percentage(0.0875);

ko.applyBindings(taxModel); 

由于它是输入文本,因此用户可以覆盖该值。

3 个答案:

答案 0 :(得分:1)

有很多方法可以做到这一点,虽然不是最优雅的方式,但这是一个简单明了的方法:

function TaxModel(initialAMount, initialPercentage) {
    this.amount = ko.observable(initialAMount);
    this.percentage = ko.observable(initialPercentage);
    this.tax = ko.computed(
        {
            read:function() {
              if (this.amount() === initialAmount) { return 200.00; }
              return this.amount() * this.percentage();
        },
        deferEvaluation: true 
    }, this);
}

并将对构造函数的调用更改为:

var taxModel = new TaxModel(100.00, 0.0875);

就像我说的那样:直截了当但有一些粗糙的边缘。例如,如果用户更改回等于200.00的确切内容,则上述计算也将返回initialAmount。这个问题没有真正提到对这个地形的任何要求,并且应该直接将上述内容更改为更精细的版本,该版本具有更好的if条件(例如make amount到可写的计算中observable将在第一次编辑时设置“changedByUser”标志。

答案 1 :(得分:1)

这是另一种方式,我不太确定我是否喜欢它。 JSFiddle

function TaxModel(intAmt, intPer, intTax) {
    var self = this;
    self.amount = ko.observable(intAmt);
    self.percentage = ko.observable(intPer);
    self.tax = ko.observable(intTax);

    self.amount.subscribe(function(newValue){
        self.tax(calcTax());
    });

    self.percentage.subscribe(function(newValue){
        self.tax(calcTax());
    });

    function calcTax(){
        return self.amount() * self.percentage();
    }
}

ko.applyBindings(new TaxModel(100,0.0875)); 

答案 2 :(得分:0)

实际上我决定做的是使用字段onload

添加initialTax百分比
if (this.onload()) {
   return this.initialTax
} else {
   // do calculation.
}