2013-03-01 11 views
6

Otrzymuję "SCRIPT5002: oczekiwana funkcja", co dzieje się tylko w IE. Obecnie testuję w stosunku do wersji 9. Dzieje się tak, gdy używam wcześniej zdefiniowanych obliczeń obserwowalnych wewnątrz innych obliczalnych obserwowalnych.Obliczenie z Knockout daje oczekiwany błąd funkcji tylko w IE.

Moja aplikacja jest nieco bardziej skomplikowane niż to, więc ja powielana błąd ze znacznie prostszą kodu poniżej. Błąd występuje w linii z = self.subtotal(); po wprowadzeniu numeru dla Numer 1, Numer 2 i Numer 3 (i tabulator).

Ten błąd nie występuje w Chrome lub Firefox i mam google na dłuższą chwilę. Mam nadzieję, że ktoś pomoże mi mnie odtrącić.

Oto link do jsfiddle: http://jsfiddle.net/kCmTg/

Oto 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()); 
}); 

Oto 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" /> 

Odpowiedz

7

To ma podobną przyczynę do tej: knockout.js Computed observable called twice in Internet Explorer i jest spowodowane faktem, że w IE < 10, Knockout ma specjalny kod, aby poradzić sobie z uzyskaniem wartości autouzupełniania z pola. Robi to, nawet jeśli pole jest tylko do odczytu, tak jak w twoim przypadku. Sprawdza się jednak dla atrybutu autocomplete. Więc można go naprawić tak:

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

Istnieje również bug in Knockout w grę tutaj - że będzie zastąpić obliczony obserwowalne przekazywane do wiązania dwukierunkowych. Zostało to już naprawione w wersji rozwojowej Knockout, która ma być wydana w wersji 2.3.0 (prawdopodobnie w kwietniu 2013 r.). Aby obejść ten problem, można przekazać wartość obserwowalny do wiązania zamiast komputerowej obserwowalnym sobie coś takiego:

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

Dzięki za nieco większą jasność w kwestiach i trochę bardziej zwięzłą poprawkę. Wprowadziłem już rozwiązanie Judy przed zobaczeniem tej opcji i opuściłem ją z innych powodów, które nie mają związku z tą dyskusją. Uważam jednak, że jest to dokładniejsza odpowiedź. – EJDev

+0

Miał podobny problem i był w stanie naprawić go przy użyciu drugiej poprawki, umieszczając '()' na wartości w 'data-bind'. Świetna robota. – vapcguy

3

Wydaje się pan odkrył błąd w IE lub KnockoutJS, prawdopodobnie odsłonięte przez wiązania Knockout, gdzie Knockout przesuwa wartość do obserwowalnego, ale w IE9 nadpisuje właściwość.

ten nie występuje na IE10, co sugeruje, że jest to błąd w IE9. Wydaje mi się, że Knockout ma coś, co sprawdza, czy pewna wartość jest zapisywalną funkcją, którą można zapisać, i jest zgłaszana niepoprawnie na IE9.

Co ciekawe, jeśli zmienisz KO obliczane użyć do zapisu/odczytu, błąd przestaje:

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

Być może, że to wystarczy obejść?

+1

Ta praca będzie absolutnie w porządku. Dziękuję bardzo za Twoją pomoc! – EJDev

0

Proszę sprawdzić, jeśli obserwowalne ma wartość jest przekazywana jako parametr lub nie . na przykład budżetlineviewmodel.total = ogółem (5). Próbowałem używać budgetlineviewmodel.total = 5., ale bez powodzenia.

Knockout obserwable są tylko funkcje wewnętrznie i mieć trzeba przekazać wartość w nawiasach, które wewnętrznie zwracają taką samą wartość.

Chrom jest łagodny, umożliwiając budgetlineviewmodel.total() tolerować wartości zerowej, gdy parametr nie jest przekazywana.

mam nadzieję, że to pomoże.

Pozdrawiam!

budgetlineviewmodel.Save = function() {   
     var currentTotalAmt = $('#txtTotal').val(); 
     budgetLineViewModel.Total(currentTotalAmt); 
} 
Powiązane problemy