Marek M.
Marek M.

Reputation: 3951

Communication between ViewModels in KnockoutJS

I'm trying to implement communication between my view models in a knockoutjs driven application. I scaffolded it using yeoman tool, and as you can see it uses AMD:

define(['knockout', 'signals', 'text!./nav-bar.html'], function(ko, Signal, template) {

    function NavBarViewModel(params) {
        this.route = params.route;
    }

    return { viewModel: NavBarViewModel, template: template };

});

I have to define an object that I would later use to dispatch events, right? Something like that:

var EventDispatcher = {
    itemClicked: new Signal()
};

And then, whenever something happens in the NavBarViewModel I'd like to do:

EventDispatcher.itemClicked.dispatch();

The problem is - where should I put this EventDispatcher thing? It's obvious that it should be some kind of a global object, so that every VM could get a hold on it, but it would be ugly. Dependency injection came to mind, since everything else in this architecture I choose is done this way, but how to achieve that? I come from WPF, MVVM world, and so far I've used MVVMLight framework which had this great Messenger component. Is there anything like that in the JS world (and if it's js-signals lib I'm already using, then how should I use it to achieve my goal?)

I could also use the subscribable object built into the knockout fw, but the question still stands - where to put it (or how to share the instance between VMs)?

Upvotes: 2

Views: 1000

Answers (1)

James Donnelly
James Donnelly

Reputation: 128856

You'd quite simply inject it by including it in your define.

First, create a new file, EventDispatcher.js with your EventDispatcher code inside (and other relevant Knockout bits, like returning the view model and whatnot).

Then in your current file add it in:

define([ ... , ... , "EventDispatcher"], function( ... , ... , EventDispatcher )

Now you can simply call its methods within this file by using:

EventDispatcher.itemClicked.dispatch()

(Where EventDispatcher is what we've named it in our define parameters).

Do bear in mind though that your EventDispatcher.js file will also need the signals file passed to it through its own define wrapper.

Upvotes: 1

Related Questions