Knockout.js modifies the value before ko.observable () write

I have a working model with many variables.

I am using autoNumeric ( http://www.decorplanit.com/plugin/ ) to format text in a text box. I would like to use the data obtained using the input field in the calculated observable, but if the visible text field with formatting is changed, the formatting will also be saved in a variable.

How can I observe only the value of an input field without formatting?

I think the best way to do this would be to getter / setter for the observable and remove the formatting when the value is set. I could not find a solution in the documentation for the knockout to write get / set methods for ko.observable (), and ko.computed () could not save the value.

I do not want to use hidden fields or additional variables. Is it possible without this?

+5
source share
2 answers

Solution as shown at 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;
};

And later

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

You can use ko.computed () for this. You can specify the recording option, see Recordable Computed Observed Files

Example (taken from the knockout documentation):

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());
+1
source

All Articles