2013-10-21 10 views
5

Attualmente ho due funzioni di estensione Knockout. Si aggiunge un membro all'osservabile mentre l'altro intercetta le operazioni di lettura e scrittura.Qual è un buon modello per conservare le proprietà personalizzate create in un'estensione Knockout?

Quando si combinano i metodi di estensione, l'ordine dell'applicazione ha un effetto indesiderato.

Esempi di codice semplificato di seguito.

ko.extenders.format = function(target) { 
    var result = ko.computed(function(){ 
     return "$" + target(); 
    }); 

    target.formatted = result; 

    return target; 
}; 

ko.extenders.numeric = function(target, precision) { 
    var result = ko.computed({ 
     read: function() { 
      var current = parseFloat(target()); 
      return current.toFixed(precision); 
     }, 
     write: function(newValue) { 
      newValue = parseFloat(newValue); 
      target(newValue.toFixed(precision)); 
     } 
    }); 

    return result; 
}; 

Nel metodo numerica posso controllare per il membro formattato e assegnarlo alla nuova calcolata, ma non voglio dare conoscenza dell'altro metodo. Anche questo non sarà mantenibile se deciderò di aggiungere più membri dall'osservabile o dalle estensioni.

if(target.hasOwnProperty("formatted")){ 
    result.formatted = target.formatted; 
} 

Ecco un violino senza la correzione hasOwnProperty. http://jsfiddle.net/gs5JM/2/

Si noti che MyValue4 - Formato: è vuoto a causa dell'ordine dell'applicazione di estensione e della perdita del membro formattato.

Esiste uno schema migliore per ottenere lo stesso risultato finale e rendere il codice più flessibile?

risposta

1

Il problema è che l'estensore format si riferisce all'originale osservabile e numeric ne crea uno nuovo. Quindi, format e numeric funzionano con osservabili completamente diversi. Sembra che dovresti considerare di restituire l'osservabile originale in entrambi i casi.

vorrei riscrivere il numeric in questo modo:

ko.extenders.numeric = function(target, precision) { 

    ko.computed(function(){ 
     var current = parseFloat(target()); 
     target(isNaN(current) ? 0 : current.toFixed(precision)); 
    }); 

    return target; 
}; 

Anonymous computed creerà un abbonamento a target valore cambia con valutazione immediata. La funzione di valutazione cercherà di analizzare un valore e riassegnare il valore numerico preci- so al target osservabile.

http://jsfiddle.net/gs5JM/3/

Nota: You should not care about possible circular dependency because KO will not re-evaluate computed while it's already evaluating.

+0

Grazie per la risposta. Non ero a conoscenza del fatto che un anonimo ko.computed avrebbe funzionato in quel modo, ma ha senso. –

+0

Funziona perfettamente per osservabili e campi calcolati con un metodo di scrittura, ma fallisce quando è calcolato con solo un metodo di lettura. Nell'estensione numerica iniziale ho incluso sia una funzione di lettura che di scrittura in modo da poterla utilizzare in entrambi gli scenari. Hai un suggerimento se non è osservabile scrivibile? –

+0

Sarà uno scenario molto strano quando è necessario un extender per scrivere in osservabili di sola lettura. Potresti spiegare in dettaglio? –