2012-09-28 12 views
8

Este parece ser un enfoque común para desinfectar/validar/formatear datos con nocaut cuando se vincula a un campo de entrada, crea un enlace personalizado reutilizable que utiliza un observable calculado. Básicamente, amplía el enlace de valor predeterminado para incluir un interceptor que formateará/desinfectará/validará la entrada antes de escribir/leer.Knockout.js Aumento del enlace de valor con el interceptor

ko.bindingHandlers.amountValue = { 
    init: function (element, valueAccessor, allBindingsAccessor) { 
    var underlyingObservable = valueAccessor(); 

    var interceptor = ko.computed({ 
     read: function() { 
     // this function does get called, but it's return value is not used as the value of the textbox. 
     // the raw value from the underlyingObservable is still used, no dollar sign added. It seems like 
     // this read function is completely useless, and isn't used at all 
     return "$" + underlyingObservable(); 
     }, 

     write: function (newValue) { 
     var current = underlyingObservable(), 
      valueToWrite = Math.round(parseFloat(newValue.replace("$", "")) * 100)/100; 

     if (valueToWrite !== current) { 
      // for some reason, if a user enters 20.00000 for example, the value written to the observable 
      // is 20, but the original value they entered (20.00000) is still shown in the text box. 
      underlyingObservable(valueToWrite); 
     } else { 
      if (newValue !== current.toString()) 
      underlyingObservable.valueHasMutated(); 
     } 
     } 
    }); 

    ko.bindingHandlers.value.init(element, function() { return interceptor }, allBindingsAccessor); 
    }, 

    update: ko.bindingHandlers.value.update 
}; 

ejemplo jsFiddle: http://jsfiddle.net/6wxb5/1/

Me estoy perdiendo algo? He visto este método usado en todas partes, pero no parece funcionar completamente. La función de lectura parece completamente inútil ya que no se usa para nada ..., y en la función de escritura, al ingresar "23.0000" se cambia el valor escrito a 23, pero los valores del cuadro de texto no se actualizan.

Respuesta

13

El problema proviene de la parte update de su enlace personalizado. Esta parte actualizará el campo en función del valor del modelo original. Por lo tanto, el controlador de eventos adjunto en el init enviará el nuevo valor a través de su capacidad de escritura calculada, pero la actualización del campo realmente ocurre en el update.

Una opción es aplicar el valor vinculante de su función init y omita la función update como:

ko.bindingHandlers.amountValue = { 
    init: function (element, valueAccessor, allBindingsAccessor) { 
    var underlyingObservable = valueAccessor(); 

    var interceptor = ko.computed({ 
     read: function() { 
     // this function does get called, but it's return value is not used as the value of the textbox. 
     // the raw value from the underlyingObservable, or the actual value the user entered is used instead, no 
     // dollar sign added. It seems like this read function is completely useless, and isn't used at all 
     return "$" + underlyingObservable(); 
     }, 

     write: function (newValue) { 
     var current = underlyingObservable(), 
      valueToWrite = Math.round(parseFloat(newValue.replace("$", "")) * 100)/100; 

     if (valueToWrite !== current) { 
      // for some reason, if a user enters 20.00000 for example, the value written to the observable 
      // is 20, but the original value they entered (20.00000) is still shown in the text box. 
      underlyingObservable(valueToWrite); 
     } else { 
      if (newValue !== current.toString()) 
      underlyingObservable.valueHasMutated(); 
     } 
     } 
    }); 

     ko.applyBindingsToNode(element, { value: interceptor }); 
    } 
}; 

violín Actualizado: http://jsfiddle.net/rniemeyer/Sr8Ev/

+0

Gracias, que fue frustrante;) –

+0

violín actualizada. http://jsfiddle.net/Sr8Ev/19/ –

Cuestiones relacionadas