3

Is it possible to overload the setter on observable to prevent setting its value in some cases? Say with a function which will trigger before setting observable, like this:

function(value) {
    if (value === 'ok') {
        proceed; //set value of observable
    } else {
        break; //do not set observable
    }
}

I guess that it can be achieved by using subscriptions, but I am not fully aware how.

Not that I'm using knockout 3.0.

Jeroen
  • 60,696
  • 40
  • 206
  • 339
Matt Mcdon
  • 185
  • 1
  • 1
  • 13

1 Answers1

6

You can use writable computed observable with read and write functions:

var _prop = ko.observable();

var prop = ko.computed({
    read: function() {
        return _prop();
    },
    write: function(value ) {
        if (value === 'ok') {
            _prop(value); //set value of observable
        }
        // else do not set observable
    }
});
manji
  • 47,442
  • 5
  • 96
  • 103
  • 1
    +1 but recommend that _prop is itself an observable, not just a plain value. – Daniel Earwicker Oct 24 '14 at 12:22
  • @DanielEarwicker That depends on intended usage, right? In some cases the overhead may not be worth it, e.g. if you don't have any other/direct dependencies on `_prop`. – Jeroen Oct 24 '14 at 12:26
  • @DanielEarwicker, agree with Jeroen, `_prop` will most of the time be the private backing field and `prop` the observable to bind to. – manji Oct 24 '14 at 12:31
  • Here's what I'm talking about: http://jsbin.com/zuvujutazi/1/edit?html,js,output - if you don't use an observable for `_prop` (as in the top/red example) then no change notifications will come out of `prop` when its value changes. – Daniel Earwicker Oct 24 '14 at 12:43
  • @DanielEarwicker, you are right, computed will notify changes only if they track observables. When using a plain js variable as backing field, nothing is tracked. Answer fixed. – manji Oct 24 '14 at 12:57
  • But is it possible to achieve it with subscriptions? I have already this observable in my autogenerated viewmodel and if possible I wouldn't like to change that observable into computed. – Matt Mcdon Oct 24 '14 at 16:24
  • 1
    subscription are not meant to be used for this. You can however follow the solution in this [answer](http://stackoverflow.com/questions/20691374/how-might-i-cancel-a-change-to-an-observable-array-w-knockout-3-0) which may help you. Can't you add a computed observable to your autogenerated viewmodel that uses the existing old observable? – manji Oct 24 '14 at 16:30