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?
You can use ko.subscribable
to implement a simple pub/sub message bus:
ko.subscribable.subscribe
to subscribe to new messagesko.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.
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);
}
};
}());
var comp1 = function(params) {
this.addToNotif = function(){
postbox.publish("comp1 was here");
}
}
...
postbox.subscribe(function(message) {
self.notifs.push(message);
});