Nillus
Nillus

Reputation: 1199

Discriminate if knockout observable has been changed by user or programatically

I have a model with an observable, binded to an input html field with value binding.

I operate on this observable in many ways, but I'd need to distinguish if my observable has been changed by the user altering the input value or by a call to myObservable(someValue) programatically. I also have a custom binding to perform some operations like formatting strings, but it is accessed in both cases, and so is a subscription.

So, I would need, if possible, in a custom binding or in a subscription handler, to use something like

if (this.hasBeenAlteredByUser()) //do something
else //something else

I would avoid if possible keyboard event monitoring.

Upvotes: 0

Views: 53

Answers (2)

Nillus
Nillus

Reputation: 1199

I do not think it is a case of xy-problem. The fact is that I have many observable binded to inputs, something like 250+ observables, and there are many ways they can be altered, some influences the others, some changes when xhr's return, and then user can also alter them. In that case some further action must be performed. Problem is: distinguish when a binded obs is altered by muliple points in code, not necessarily code I can refactor, with obs("something"), and when it is edited by user - no xy, this is what I was asking. There could be other ways to achieve same result without needing to discriminate, but discriminating was shortest, easiest way and I have to refactor at minimum existing, very long, code.

In effec, no possible solution is present in subscription or bindings to achieve source disambiguation.

To understand when a user effectively alter an oservable directly through input I solved delegating change event of every input to an handler in a container which marks the relative observable as user altered until subscription/binding unflags it when special treatment for user specific input is performed.

Thanks for assistance, you answered my question telling me there's no way built in in ko to discriminate update source

Upvotes: 0

Jeroen
Jeroen

Reputation: 63830

I think that what you want is not possible. You're not quite explicit about exactly when you need the distinction, but if it is in custom binding handlers, manual subscriptions, extenders, etc, I'd think there is no way to know the source of the change.

You may have a case of the XY-problem, but you'd need to provide more details (probably in a fresh question) about what you actually want to do before we could provide any solutions.

One typical pattern that comes to mind though that may be a solution to your Y-problem, is to use a writeable computed observable and an extra normal observable, e.g.:

var MyViewModel = function() {
    var self = this;

    self.myText = ko.observable('initial value');

    self.myTextSpecial = ko.computed({
        read: self.myText,
        write: function(newVal) {
            // Do special stuff here!
            // Plus also:
            self.myText(newVal);
        }
    });
}

You can then manipulate the "backing observable" myText directly when you want to, and bind the computed observable to your input (or vice versa). Only when writing the computed observable will the "special stuff" happen.

Upvotes: 4

Related Questions