Knockout computed дава функция очаквана грешка само в IE

Получавам „SCRIPT5002: Очаква се функция“, което се случва само в IE. В момента тествам срещу версия 9. Това се случва, когато използвам предварително дефинирана изчислена наблюдаема вътре в друга изчислена наблюдаема.

Моето приложение е малко по-сложно от това, така че възпроизведох грешката с много по-опростен код по-долу. Грешката възниква на ред z = self.subtotal();, когато въведете число за номер 1, номер 2 и номер 3 (и разделяне).

Тази грешка не се появява в Chrome или Firefox и търсих в Google от известно време. Надявам се, че някой може да ми помогне да ме отлепя.

Ето връзката към 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" />

person EJDev    schedule 01.03.2013    source източник


Отговори (3)


Това има причина, подобна на тази: knockout.js Computed observable, извикан два пъти в Internet Explorer и се причинява от факта, че в IE‹10, Knockout има някакъв специален код за справяне с получаването на стойност за автоматично довършване от полето. Той прави това дори ако полето е само за четене, както във вашия случай. Той обаче проверява за атрибута autocomplete. Така че можете да го поправите по следния начин:

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

Тук също има бъг в Knockout – че ще презапише изчислен наблюдаемо преминава към двупосочно свързване. Това вече е коригирано във версията за разработка на Knockout, която ще бъде пусната като версия 2.3.0 (вероятно през април 2013 г.). За да заобиколите това, можете да предадете стойността на наблюдаемата величина към обвързването вместо самата изчислена наблюдаема величина, като това:

<input id="Subtotal" type="text" data-bind="value: subtotal()" readonly="readonly" />
person Michael Best    schedule 02.03.2013
comment
Благодаря за малко повече яснота по проблемите и малко по-кратко решение. Вече бях приложил решението на Judah, преди да видя тази опция, и я оставих поради други причини, които не са от значение за тази дискусия. Все пак вярвам, че това е по-точният отговор. - person EJDev; 04.03.2013
comment
Имах подобен проблем и успях да го поправя, като използвах втората ви корекция, като поставих () върху стойността в data-bind. Страхотна работа да го намериш. - person vapcguy; 20.03.2015

Изглежда, че сте открили грешка в 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);

Може би това е достатъчно заобиколно решение?

person Judah Gabriel Himango    schedule 01.03.2013
comment
Тази работа ще бъде абсолютно наред. Благодаря ви много за помощта! - person EJDev; 02.03.2013

Моля, проверете дали вашият observable има стойност, която се предава като параметър или не. например budgetlineviewmodel.total = total(5). Опитах да използвам budgetlineviewmodel.total = 5. но без успех.

Knockout Observables не са нищо друго освен вътрешни функции и трябва да предадете стойност в скоби, които вътрешно връщат същата стойност.

Chrome е снизходителен, като позволява на budgetlineviewmodel.total() да толерира нулева стойност, когато не се предава параметър.

Надявам се това да помогне.

наздраве !

budgetlineviewmodel.Save = function () {        
        var currentTotalAmt = $('#txtTotal').val();
        budgetLineViewModel.Total(currentTotalAmt);
}
person Sushrut Kanetkar    schedule 05.05.2015