2013-03-01 104 views
6

我得到一个“SCRIPT5002:函数预期”,只发生在IE中。我目前正在对版本9进行测试。它发生在我使用另一个计算的observable内的先前定义的计算可观察值时。Knockout计算给出了函数在IE中的预期错误

我的应用程序比这个更复杂一点,所以我用下面更简单的代码重现了错误。输入号码1,号码2和号码3(和制表符)时,错误发生在线路z = self.subtotal();上。

这个错误在Chrome或Firefox中不会发生,我已经搜索了很长一段时间。希望有人能帮助解开我。

这里是链接到的jsfiddle:http://jsfiddle.net/kCmTg/

这里是JavaScript:

function putVars() { 
    self = this; 
    self.number1 = ko.observable(); 
    self.number2 = ko.observable(); 
    self.subtotal = ko.computed(function() { 
     return parseFloat(self.number1()) + parseFloat(self.number2()); 
    }, self, { deferEvaluation: true }); 

    self.number3 = ko.observable(); 
    self.number4 = ko.observable(); 
    self.total = ko.computed(function() { 
     var x, y, z; 
     x = self.number3(); 
     y = self.number4(); 
     z = self.subtotal(); 
     return parseFloat(x) + parseFloat(y) + parseFloat(z); 
    }, self, { deferEvaluation: true }); 
} 

$(function() { 
    ko.applyBindings(new putVars()); 
}); 

下面是HTML:

<h4>Calc 1</h4> 
<label for="Number1">Number 1: </label><input id="Number1" type="text" data-bind="value: number1" /> 
<label for="Number2">Number 2: </label><input id="Number2" type="text" data-bind="value: number2" /> 
<label for="Subtotal"><b>Subtotal: </b></label><input id="Subtotal" type="text" data-bind="value: subtotal" readonly="readonly" /> 
<hr /> 
<h4>Calc 2</h4> 
<label for="Number3">Number 3: </label><input id="Number3" type="text" data-bind="value: number3" /> 
<label for="Number4">Number 4: </label><input id="Number4" type="text" data-bind="value: number4" /> 
<label for="Total"><b>Total:</b> </label><input id="Total" type="text" readonly="readonly" data-bind="value: total" /> 

回答

7

这和这个问题有类似的原因:knockout.js Computed observable called twice in Internet Explorer是由于在IE中有这样一个事实造成的,Knockout有一些特殊的代码来处理从字段中获得一个自动完成值。即使这个字段是只读的,就像你的情况一样。但它确实检查autocomplete属性。所以,你可以解决它是这样的:

<input id="Subtotal" type="text" data-bind="value: subtotal" autocomplete="off" readonly="readonly" /> 

还有一个bug in Knockout在这里打球 - 这将覆盖一个计算观察到的传递到双向绑定。 Knockout的开发版本已经在版本2.3.0(可能在2013年4月)发布。要解决这个问题,你可以观察到的值传递给结合,而不是计算观察的本身,就像这样:

<input id="Subtotal" type="text" data-bind="value: subtotal()" readonly="readonly" /> 
+0

感谢您对问题的更加清晰和更简洁的解决方法。在看到这个选项之前,我已经实施了犹大的解决方案,并将其留给了与本次讨论无关的其他原因。我相信这是更准确的答案。 – EJDev 2013-03-04 15:24:06

+0

有类似的问题,并能通过使用第二个修复程序来修复它,将'()'放在'data-bind'中的值上。伟大的工作发现。 – vapcguy 2015-03-20 06:52:56

3

看来你已经发现了一个bug IE或KnockoutJS,可能暴露在Knockout的绑定中,其中Knockout将一个值推入可观察对象,但在IE9中,它会覆盖该属性。

这不会发生在IE10上,表明这是IE9中的一个错误。我猜Knockout有一些东西在检查一些值是否是一个可写的可观察函数,并且它在IE9上被错误地报告。

有趣的是,如果你改变KO计算使用读/写,错误停止:

self.subtotal = ko.computed({ 
    read: function() { 
     return parseFloat(this.number1()) + parseFloat(this.number2()); 
    }, 
    write: function(val) { } 
}, self); 

也许这是一个足够的变通?

+1

这个解决方法绝对没问题。非常感谢你的帮助! – EJDev 2013-03-02 01:22:50

0

请检查,看看你是否观察到已被作为一个参数或没有通过价值。例如budgetlineviewmodel.total = total(5)。我试过使用budgetlineviewmodel.total = 5,但没有成功。

Knockout Observable只是内部函数,您必须在括号内传递一个内部返回相同值的值。

Chrome在允许budgetlineviewmodel.total()在不传递参数时容许空值的情况下宽松。

希望这有助于。

干杯!

budgetlineviewmodel.Save = function() {   
     var currentTotalAmt = $('#txtTotal').val(); 
     budgetLineViewModel.Total(currentTotalAmt); 
} 
相关问题