2012-09-28 11 views
8

To wydaje się być powszechnym podejściem do sanityzacji/sprawdzania poprawności/formatowania danych z nokautem podczas wiązania z polem wejściowym, tworzy wielokrotne do użytku niestandardowe powiązanie, które wykorzystuje obliczone obserwowalne. Zasadniczo rozszerza on domyślne powiązanie wartości, tak aby zawierał przechwytywacz, który będzie formatował/sanityzował/sprawdzał dane wejściowe przed zapisaniem/odczytaniem.Knockout.js Rozszerzanie wiązania wartości z przechwytywaczem

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 
}; 

jsFiddle przykład: http://jsfiddle.net/6wxb5/1/

Am I czegoś brakuje? Widziałem tę metodę używaną wszędzie, ale wydaje się, że w pełni nie działa. Funkcja odczytu wydaje się zupełnie bezużyteczna, ponieważ nie jest w ogóle używana. W funkcji zapisu wpisanie wartości "23.0000" powoduje zmianę wartości zapisanej na 23, ale wartości pól tekstowych nie są aktualizowane.

Odpowiedz

13

Ten problem pochodzi z części niestandardowego powiązania z . Ta część zaktualizuje pole w oparciu o oryginalną wartość modelu. Tak więc program obsługi zdarzeń dołączony w numerze init wyśle ​​nową wartość za pomocą obliczanego przez ciebie zapisu, ale aktualizacja tego pola faktycznie nastąpi w update.

Jedną z opcji jest, aby zastosować wiązania z funkcją init wartości i pominąć funkcję update jak:

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

Aktualizowane skrzypce: http://jsfiddle.net/rniemeyer/Sr8Ev/

+0

Dzięki, że było frustrujące;) –

+0

aktualizowane skrzypce. http://jsfiddle.net/Sr8Ev/19/ –

Powiązane problemy