Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239814

Communication between multiple applications

Say I have an angular SPA running inside a browser (window 1). And say that there's some activity that leads to us launching a separate angular application inside of a new window (opened by $window.open()) (window 2).

Windows 1 & 2 want to stay somewhat connected. They're running different applications but they're both dealing with the same subject matter. When one changes state, the other might need to react to that. And vice versa.

I'm looking for some good way for these two apps, in two separate browser windows, to send events back and forth.

Now, for fun, there might be another window (window 3) running the same application as window 1. This separate instance should not be interfered with in any way by windows 1 & 2. And, of course, window 3 could launch it's own equivalent of window 2 (window 4).

So windows 1 & 2 (running different apps) should be able to message back and forth. And windows 3 & 4 similarly. But 1 shouldn't affect 3 & 4, and so on.

The obvious relationship between them is that window 1 called $window.open() and window 2 can access $window.opener - so they can both access window objects - but how do I "angular-ise" up this situation?

The current implementation is using $localStorage and watching for storage events to link windows 1 & 2,but of course this completely fails the non-interference requirement once windows 3 & 4 show up.

Upvotes: 1

Views: 2987

Answers (2)

Nicolas ABRIC
Nicolas ABRIC

Reputation: 4935

If you are lucky enough to have all of your window on the same domain then you can use postMessage as already mentioned or even better HTML5 localStorage. You have an article and demo available here. Mainly what's going on here :

All window listen to storage event with something like :

window.addEventListener("storage", handle_storage, false); 

For every window you can have a different handle_storage function or a common one that checks which url is responsible for the storage event.

Advantages :

  • No reference to other windows,
  • WILL work even if the main window is closed,
  • Standard and widely available IE8+, FF3.5+, Chrome4+,
  • "Native" Javascript no external library. Easy integration within your Angular JS app

Disadvantages :

  • None (at least from what I know)

Hope this will help.

Upvotes: 2

Greg Burghardt
Greg Burghardt

Reputation: 18888

This sounds like a good case for using application events.

You'll want one object to have a publish/subscribe interface:

var dispatcher = {
    subscriptions: {},

    publish: function(eventName, publisher, data) {
        // loop through subscribers and notify them, passing publisher and data
        // var subscriber = this.subscribers[eventName][i];
        // subscriber.callback.call(subscriber.context, publisher, data);
    },

    subscribe: function(eventName, context, callback) {
        this.subscriptions[eventName] = this.subscriptions[eventName] || [];
        this.subscriptions[eventName].push({
            context: context,
            callback: callback
        });
    }
};

When you open a new window, set this object reference as a property on the new window.

var win = window.open(...);
win.dispatcher = dispatcher;

Now each window, including the "top" window should have a global variable called dispatcher that you can use to subscribe to and publish events:

(from main window)

dispatcher.subcribe("item.added", this, function(publisher, data) {
    // "publisher" is the object publishing the event
    // "data" is arbitrary data passed along in the event
});

(from a sub window)

dispatcher.publish("item.added", this, {
    name: "Foo"
});

I haven't used AngularJS much yet, so I'm not sure if it comes with some sort of event framework outside of DOM events. There are a bunch of implementations of the pub/sub model in JavaScript, and you could probably throw a dart at a Google search and land on one. I created a simple JavaScript class library that might fit the bill. It has no external dependencies: https://github.com/gburghardt/events

Advantages

  • Performs very well, as it doesn't rely on the HTTP request/response lifecycle
  • Fairly simple to set up
  • Cross browser support with no hacks or polyfills

Disadvantages

  • If the main window closes, then your sub windows will lose their connection to the outside world and published events will fall on deaf ears.

Upvotes: 2

Related Questions