2013-12-11 57 views
1

假設我在瀏覽器(窗口1)內運行了角度SPA。並且說有一些活動導致我們在一個新窗口內打開一個單獨的角度應用程序(由$window.open()打開)(窗口2)。多個應用程序之間的通信

Windows 1 & 2想保持一定的連接。他們正在運行不同的應用程序,但他們都處理相同的主題。當一個人改變狀態時,另一個人可能需要對此作出反應。反之亦然。

我正在尋找這兩個應用程序的一些好方法,在兩個單獨的瀏覽器窗口中來回發送事件。

現在,爲了好玩,可能會有另一個窗口(窗口3)運行與窗口1相同的應用程序。這個單獨的實例不應該以任何方式被Windows 1 & 2干擾。當然,窗口3可以啓動它自己的窗口2(窗口4)。

因此Windows 1 & 2(運行不同的應用程序)應該能夠來回消息。類似地,窗戶3。但是1不應該影響3,依此類推。

它們之間最明顯的關係是窗口1名爲$window.open()和窗口2可以訪問$window.opener - 所以它們都可以訪問window對象 - 但我如何「的角度-ISE」了這種情況呢?

當前的實施方案使用$localStorage並觀察存儲事件以鏈接窗口1 & 2,但當然這完全不符合一旦出現窗口時的無干擾要求。

+0

聽起來像網絡套接字可能適合該法案:http://www.html5rocks.com/en/tutorials/websockets/basics/ –

+0

@ChrisHardie - 如果可能的話,我希望保留所有的客戶端。 –

+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,s o我不確定它是否包含DOM事件之外的某種事件框架。在JavaScript中有很多pub/sub模型的實現,你可以在Google搜索中投擲一個Dart,然後登陸一個。我創建了一個簡單的JavaScript類庫,可能適合賬單。它沒有外部依賴:https://github.com/gburghardt/events

優勢

  • 有很好的表現,因爲它不依賴於HTTP請求/響應週期
  • 相當簡單的設置
  • 跨瀏覽器支持沒有黑客或polyfills

缺點

  • 如果主窗口關閉,那麼您的子窗口將失去與外部世界的連接,發佈的事件將會充耳不聞。
+0

當您需要在同一個窗口中發送不同的Angular模塊時,這種模式也能很好地工作。 –

+0

我是新來的,所以我不能發表評論Nicolas ABRIC的答案,但我可以想到使用localStorage的一個缺點是事件數據在頁面瀏覽之間依然存在。在事件中傳遞的數據本質上是短暫的 - 使用然後丟棄。使用localStorage會使事件數據保持不變,這在實現此操作之前可能需要考慮安全隱患。 上面概述的方法使事件數據暫時保持不變。 –

2

如果你足夠幸運,有所有你的窗口在同一個域,那麼你可以使用postMessage前面已經提到,甚至更好的HTML5 localStorage。您有一篇文章和演示可用here。主要是什麼是怎麼回事:

所有窗口監聽存儲事件的東西,如:

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

對於每一個窗口,你可以有不同的handle_storage功能或常見的一種,檢查其網址是負責存儲事件。

優點:

  • 沒有參考其他窗口,如果關閉主窗口
  • 甚至會工作,
  • 標準和廣泛使用IE8 +,FF3.5 +,Chrome4瀏覽器+,
  • 「本地」Javascript沒有外部庫。您的角度JS應用程序中輕鬆集成

缺點:

  • 無(據我所知至少)

希望這會有所幫助。

+0

我不清楚這是如何滿足非干擾要求的 - 我可以在不同的會話中運行兩個應用程序實例,我*不希望它們互相干擾。 –

相關問題