Routed events in Knockout?

76 Views Asked by At

Are there any available tweak to make Knockout support routed events?

In my perticular case I want to handle context-menu-events in the root-vm of my view and let any nested vm to set up a context-menu trigger like this:

event: { contextmenu: OnContextMenu }

If the OnContextMenu-handler is not defined on the current vm it should route the event to it's parent-vm and so on until a handler is found.

Currently I have to do like this (which is kind of error prone)

event: { contextmenu: $parents[3].OnContextMenu }

Or are there other ways of doing this allready?

2

There are 2 best solutions below

0
On BEST ANSWER

Found a simple solution. I'm using the built-in DOM event bubbling and then on the root-element I catch the event and get the vm using ko.dataFor, like this:

self.OnContextMenu = function (vm, e) { // the root-vm
  vm = ko.dataFor(e.originalEvent.target);
  if (vm && vm.contextMenu) {
    self.openContextMenu(vm.contextMenu);
  }
};
0
On

I have previously used a pattern where I search up through a hierarchy of view-models via the $parentContext, until I find whatever it is I need. I quickly adapted it for your code, a bit rough:

OnContextMenuSearch = function(data, event) {
    var context = ko.contextFor(event.target);
    done = false;

    while (!done) {
        if (typeof context.$data.OnContextMenu == "function") {
            // Found it! Invoke it here...
            context.$data.OnContextMenu()
            done = true;
        }
        // Check there is something to recurse up into, before assigning it! 
        // If not, we are at the $root. 
        if ('$parentContext' in context == false) done = true;
        else context = context.$parentContext;
    }
}

which would be bound with something like:

event: { contextmenu: OnContextMenuSearch }