2013-04-23 11 views
5

Mam działający model z wieloma zmiennymi.Knockout.js zmodyfikuj wartość przed ko.observable() napisz

Używam autoNumeric (http://www.decorplanit.com/plugin/) do formatowania tekstu w polu tekstowym. Chciałbym użyć obserwowanych danych pola wejściowego w obliczalnym observable, ale jeśli obserwowalne pole tekstowe z formatowaniem zostanie zmodyfikowane, formatowanie zostanie również zapisane w zmiennej.

Jak mogę obserwować tylko wartość pola wejściowego bez formatowania?

Myślę, że najlepszym sposobem, aby to zrobić, może być getter/setter do obserwowalnego i usunąć formatowanie, gdy wartość jest ustawiona. Nie mogłem znaleźć rozwiązania w dokumentacji nokautu, aby napisać metody get/set dla ko.observable(), a ko.computed() nie może przechowywać wartości.

Nie chcę używać ukrytych pól lub dodatkowych zmiennych.
Czy to możliwe bez tego?

Odpowiedz

3

Solution, jak widać na http://knockoutjs.com/documentation/extenders.html

ko.extenders.numeric = function(target, precision) { 
//create a writeable computed observable to intercept writes to our observable 
var result = ko.computed({ 
    read: target, //always return the original observables value 
    write: function(newValue) { 
     var current = target(), 
      roundingMultiplier = Math.pow(10, precision), 
      newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue), 
      valueToWrite = Math.round(newValueAsNum * roundingMultiplier)/roundingMultiplier; 

     //only write if it changed 
     if (valueToWrite !== current) { 
      target(valueToWrite); 
     } else { 
      //if the rounded value is the same, but a different value was written, force a notification for the current field 
      if (newValue !== current) { 
       target.notifySubscribers(valueToWrite); 
      } 
     } 
    } 
}); 

//initialize with current value to make sure it is rounded appropriately 
result(target()); 

//return the new computed observable 
return result; 
}; 

A później

function AppViewModel(one, two) { 
    this.myNumberOne = ko.observable(one).extend({ numeric: 0 }); 
    this.myNumberTwo = ko.observable(two).extend({ numeric: 2 }); 
} 
+0

To również tworzy dodatkową zmienną ('result = ko.computed (...)') – mhu

+0

, ale nie w viewmodel. – zeal

1

Możesz użyć ko.computed() do tego. Można określić opcję zapisu, patrz Writeable computed observables

Przykład (wzięte z dokumentacji nokaut):

function MyViewModel() { 
    this.price = ko.observable(25.99); 

    this.formattedPrice = ko.computed({ 
     read: function() { 
      return '$' + this.price().toFixed(2); 
     }, 
     write: function (value) { 
      // Strip out unwanted characters, parse as float, then write the raw data back to the underlying "price" observable 
      value = parseFloat(value.replace(/[^\.\d]/g, "")); 
      this.price(isNaN(value) ? 0 : value); // Write to underlying storage 
     }, 
     owner: this 
    }); 
} 

ko.applyBindings(new MyViewModel()); 
+0

jak powiedziałem "ko.computed() nie może przechowywać wartości" – zeal

+0

chcę av oid również tworzy więcej zmiennych. nie jest odpowiedzią. – zeal

+0

Ale jeśli użyjesz opcji zapisu, ** możesz ** zapisać wartość. Czy przejrzałeś dokumentację? – mhu