9

I have a web app that I want to convert to and SPA using ko components. I wonder how to do a kind of inter component communication.

For example I want a "notification" component in which every single component can send notifications.

I managed to find a solution by sharing an observable array in the main view model:

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

    this._notifications = ko.observableArray([]);
   this.notifications = {
        addInfo: function(text){
            self._notifications.push(text);
        }
    }
}

and

<comp1 params="{app: $data}"></comp1><br/>
<comp2 params="{app: $data}"></comp2><br/>
<notif params="{app: $data}"></notif>

See here: http://jsfiddle.net/nveron/j4829y7p/

I'm not completely satisfied with this solution, I would rather have kept the notification data in the notify component.

Do you have any idea to deal with that?

Tanner
  • 22,205
  • 9
  • 65
  • 83
rbag
  • 137
  • 1
  • 5

1 Answers1

16

You can use ko.subscribable to implement a simple pub/sub message bus:

  • ko.subscribable.subscribe to subscribe to new messages
  • ko.subscribable.notifySubscribers to publish new messages

    More about this in this article by Ryan Niemeyer.

In your case, you can create a global postbox object based on ko.subscribable. Componenents publish messages in it and notification vm subscribes to it.

You can even publish and subscribe to message by topic.

Demo: JSFiddle

postbox:

var postbox = (function() {
    var pb = new ko.subscribable();
    return {    
        subscribe: function(handler, topic) {
            pb.subscribe(handler, null, topic)
        },        
        publish: function(message, topic) {
            pb.notifySubscribers(message, topic);
        }
    };
}()); 

a component:

var comp1 = function(params) {           
    this.addToNotif = function(){
        postbox.publish("comp1 was here");
    }
}

notif:

...
postbox.subscribe(function(message) {
    self.notifs.push(message);
});
manji
  • 47,442
  • 5
  • 96
  • 103
  • 1
    Thanks, I was looking at the knockout-postbox by rniemeyer I think that will be the solution. – rbag Oct 08 '14 at 10:00