2013-03-01 98 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); 
} 
相關問題