Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reject observable value change

Tags:

knockout.js

Is there a way to reject/cancel the modification of an observable's value? Like this:

observable.subscribe (function (newvalue) {
   if ( newvalue < 0 ) {

        // cancel changing
   }
   else{ 
        // proceed with change
   }

}, this)
like image 542
Alex Avatar asked Feb 28 '13 09:02

Alex


2 Answers

Edit:

I found something else: Writeable computed observables.

Here is an example:

function AppViewModel() {
    this.field = ko.observable("initValue");
    this.computedField = ko.computed({
        read: function () {
            return this.field();
        },
        write: function (value) {
            if(value > 0) {
                this.field(value);
            }
        },
        owner: this
    });
}

So then you bind to the computed field.

/Edit

I would go with a custom binding.

Here is the tutorial for custom binding: http://learn.knockoutjs.com/#/?tutorial=custombindings

or here is the documentation: http://knockoutjs.com/documentation/custom-bindings.html

like image 134
Andras Toth Avatar answered Dec 05 '22 08:12

Andras Toth


To help reject write values I used the following:

  • Create a hidden observable that stores the value.
  • Return a writable computed observable based on the hidden observable.
  • When something is written to the computed observable, validate it before accepting it.

I extended Knockout with this code:

ko.conditionedObservable = function (initialValue, condition) {
    var obi = ko.observable(initialValue);
    var computer = ko.computed({
        read: function () { return obi(); },
        write: function (newValue) {
            //unwrap value - just to be sure
            var v = ko.unwrap(newValue);
            //check condition
            if (condition(v)) {
                //set it to the observable
                obi(v);
            }
            else {
                //reset the value
                computer.notifySubscribers();
            }
        }
    });
    return computer;
};

Use it in the object like this:

field = ko.conditionedObservable<number>(null, (v) => parseInt(v) > 0);

For more explanation check my Conditioning Knockout Observables: reject values blog.

like image 32
Kees C. Bakker Avatar answered Dec 05 '22 10:12

Kees C. Bakker