1
votes

I recently found this great component -> Knockout-Kendo.js.

I use it to handle some behaviors with kendoComboBox.

The synchronization with the viewmodel works perfectly.

I want to listen changes of the control to execute some actions based on the current selected value.

I don't see any property that I can bind in the 'data-bind' attribute to listen changes but I know that internally, the knockout-kendo component listen changes and this is how the viewmodel is able to by sync with the control.

If I try to listen the valueChange event of the control, the problem is my eventhandler is catched before the viewmodel and while running in my eventhandler, I just have the previous value of the control using the viewmodel.

Look at this binding configuration in the component. What I understand is I'm able to use 'enabled', 'search', 'data', 'value' and any other exposed properties of the telerik control. What would be nice would be to define in data-bind attribute a property 'change' with an eventhandler linked in my viewmodel and be sure my eventhandler would be called after the internal eventhandler of the knockout-kendo component.

createBinding({
    name: "kendoAutoComplete",
    events: {
        change: VALUE,
        open: {
            writeTo: ISOPEN,
            value: true
        },
        close: {
            writeTo: ISOPEN,
            value: false
        }
    },
    watch: {
        enabled: ENABLE,
        search: [SEARCH, CLOSE],
        data: function(value) {
            ko.kendo.setDataSource(this, value);
        },
        value: VALUE
    }

});

I know I can try to modify the order of bind of events to be sure my eventhandler must be called after the synchronization of the viewmodel but I think it's a very bad practice.

Anybody have an idea how I can solve this problem with elegance?

1

1 Answers

1
votes

You haven't mentioned why you want to do this. I can imagine two reasons:

  • To trigger some UI behavior/logic directly;
  • To trigger business logic (which may in turn trigger UI changes of course);

For people landing at this question with the latter case, here's an alternative solution. (This answer may not be a straight up answer to the OP's question, but seems useful enough to post it here.)


Suppose you have this basic view model:

var ViewModel = function() {
    var self = this;
    self.kendoObservable = ko.observable("Some text")
};

There are two ways you can indirectly respond to changes by Kendo. First, for simple cases, there's computed observables:

    // Option 1, add this to ViewModel
    self.dependentObservable = ko.computed(function() {
         return self.kendoObservable() === "" ? "Empty" : "Not empty"; // example
    });

This dependentObservable will be modified each time the kendoObservable changes. Basic stuff.

If you want to do something more complex when kendoObservable changes, e.g. do an AJAX call or whatnot, you may need a manual subscription:

    // Option 2, add this to ViewModel
    self.kendoObservable.subscribe(function(newValue) {
         // Possibly do an AJAX call here or whatnot. Example:
         alert("The new value is: " + newValue);
    });

This will allow you to fire some complex logic each time the kendoObservable changes. AFAIK you need to check yourself whether the newValue is actually a changed value, at least in some versions of KO.