2013-03-01 11 views
6

Ricevo un "SCRIPT5002: funzione prevista" che si verifica solo in IE. Attualmente sto testando contro la versione 9. Succede quando uso un osservabile calcolato precedentemente definito all'interno di un altro osservabile calcolato.Knockout calcolato dà errore di funzione prevista in IE solo

La mia applicazione è un po 'più complessa di così, quindi ho riprodotto l'errore con il codice molto più semplice di seguito. L'errore si verifica sulla riga z = self.subtotal(); quando si immette un numero in per Numero 1, Numero 2 e Numero 3 (e scheda).

Questo errore non si verifica in Chrome o Firefox e ho cercato su Google per un po 'di tempo. Spero che qualcuno possa aiutarmi a disimpegnarmi.

Ecco il link al jsfiddle: http://jsfiddle.net/kCmTg/

Ecco l'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()); 
}); 

Ecco l'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" /> 

risposta

7

Ciò ha una causa simile a questa: knockout.js Computed observable called twice in Internet Explorer ed è causato dal fatto che in IE < 10, Knockout ha un codice speciale per gestire l'ottenimento di un valore di completamento automatico dal campo. Lo fa anche se il campo è di sola lettura come nel tuo caso. Controlla, tuttavia, l'attributo autocomplete. Così si potrebbe risolvere il problema in questo modo:

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

C'è anche un bug in Knockout in gioco qui - che sarà sovrascrivere un osservabile calcolato passato a una rilegatura a due vie. Questo è già stato risolto nella versione di sviluppo di Knockout per essere rilasciato come versione 2.3.0 (probabilmente ad aprile 2013). Per ovviare a questo, è possibile passare il valore della osservabile per il legame al posto del sé osservabile calcolato, in questo modo:

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

Grazie per un po 'più di chiarezza sui problemi e una soluzione leggermente più succinta. Avevo già implementato la soluzione di Judah prima di vedere questa opzione e l'ho lasciata per altri motivi che sono irrilevanti a questa discussione. Credo che questa sia la risposta più accurata. – EJDev

+0

Aveva un problema simile ed è stato in grado di risolverlo usando la tua seconda correzione, mettendo '()' sul valore in 'data-bind'. Ottimo lavoro a trovarlo. – vapcguy

3

Sembra che hai scoperto un bug in IE o KnockoutJS, probabilmente esposti dai binding di Knockout, in cui Knockout sta spingendo un valore in un osservabile, ma in IE9, sovrascrive la proprietà.

Questo non si verifica su IE10, suggerendo che si tratta di un bug in IE9. Immagino che Knockout abbia qualcosa in cui sta controllando se qualche valore è una funzione osservabile scrivibile e viene segnalato erroneamente su IE9.

È interessante notare che, se si cambia KO calcolata per utilizzare una lettura/scrittura, l'errore cessa:

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

Forse è sufficiente work-around?

+1

Questo lavoro sarà assolutamente perfetto. Grazie mille per il vostro aiuto! – EJDev

0

Si prega di controllare per vedere se è osservabile ha un valore viene passato come parametro o no . ad esempio, budgetlineviewmodel.total = total (5). Ho provato a utilizzare budgetlineviewmodel.total = 5. ma senza successo.

Knockout Gli osservabili non sono altro che funzioni internamente e devi passare un valore all'interno di parentesi che restituiscono internamente lo stesso valore.

Chrome è indulgente nel consentire a budgetlineviewmodel.total() di tollerare il valore nullo quando non viene passato alcun parametro.

spero che questo aiuti.

Cheers!

budgetlineviewmodel.Save = function() {   
     var currentTotalAmt = $('#txtTotal').val(); 
     budgetLineViewModel.Total(currentTotalAmt); 
} 
Problemi correlati