多个应用程序之间的通

时间:2013-12-11 17:26:27

标签: javascript angularjs events

假设我在浏览器中运行了角度SPA(窗口1)。并且说有一些活动导致我们在新窗口内启动一个单独的角度应用程序(由$window.open()打开)(窗口2)。

Windows 1& 2想要保持一定的联系。他们正在运行不同的应用程序,但他们都在处理相同的主题。当一个人改变状态时,另一个人可能需要对此做出反应。反之亦然。

我正在为这两个应用程序寻找一些好方法,在两个独立的浏览器窗口中来回发送事件。

现在,为了好玩,可能会有另一个窗口(窗口3)运行与窗口1相同的应用程序。这个单独的实例不应以任何方式受到窗口1和1的干扰。 2.当然,窗口3可以启动它自己的窗口2(窗口4)。

所以Windows 1& 2(运行不同的应用程序)应该能够来回发送消息。和Windows 3& 4同样。但是1不应该影响3& 4,等等。

它们之间的明显关系是窗口1称为$window.open()而窗口2可以访问$window.opener - 因此它们都可以访问window个对象 - 但我如何“角度为”这种情况?

当前的实施正在使用$localStorage并观察存储事件以链接窗口1和1。 2,但当然这一次完全失败了无障碍要求一旦windows 3& 4出现。

2 个答案:

答案 0 :(得分:2)

这听起来像是使用应用程序事件的好例子。

您希望一个对象拥有发布/订阅界面:

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
        });
    }
};

当您打开一个新窗口时,请在新窗口中将此对象引用设置为属性。

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

现在每个窗口(包括“顶部”窗口)都应该有一个名为dispatcher的全局变量,您可以使用它来订阅和发布事件:

(从主窗口)

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

(来自子窗口)

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

我还没有使用过AngularJS,所以我不确定它是否带有DOM事件之外的某种事件框架。在JavaScript中有很多pub / sub模型的实现,你可能会在Google搜索上投掷一个飞镖并落在一个上。我创建了一个简单的JavaScript类库,可能符合要求。它没有外部依赖关系:https://github.com/gburghardt/events

<强>优点

  • 执行得非常好,因为它不依赖于HTTP请求/响应生命周期
  • 设置相当简单
  • 跨浏览器支持,无hacks或polyfill

<强>缺点

  • 如果主窗口关闭,那么您的子窗口将失去与外界的联系,发布的事件将被置若罔闻。

答案 1 :(得分:2)

如果您有幸将所有窗口放在同一个域中,那么您可以使用已提及的postMessage或更好的HTML5 localStorage。您有一篇文章和演示here。主要是这里发生了什么:

所有窗口都会收听存储事件,例如:

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

对于每个窗口,您可以使用不同的handle_storage函数或通用函数来检查哪个URL负责存储事件。

优点:

  • 没有引用其他窗口,
  • 即使主窗口关闭也会起作用,
  • 标准且广泛使用的IE8 +,FF3.5 +,Chrome4 +,
  • “Native”Javascript没有外部库。在Angular JS应用程序中轻松集成

缺点:

  • 无(至少从我所知道的)

希望这会有所帮助。