2017-07-28 38 views
0

我試圖在任務完成時提供警報 - 用戶可能在當時處於多個頁面中的任何一個。警報應顯示給所有頁面。Angular 2 - 跨多個瀏覽器窗口的單一服務提供商

我使用實施BehaviorSubject 的提供商,這是我的app.component.ts網頁服務 - 單個實例

在我app.component.html我有兩個組成部分,一個警報時,其他火警警報。

<alert></alert> 
<submit-service></submit-service> 

該服務發送到呈現警報的警報組件。 這工作正常,但只有在提交服務的頁面(而不是任何其他頁面) - 提交功能也在警報組件。

submit-service利用 public emit: BehaviorSubject<model> = new BehaviorSubject(new model());

一旦事件完成它,然後觸發關閉this.emit.next(_model);

在警報分量I訂閱事件

ngOnInit(): void { 
    this.service.emit.subscribe(data=> { 
      this.fireAlert(data); 
     } 
    }); 
} 

,所以我想主要的問題是,我如何跨多個頁面跨多個實例訂閱單個服務?

編輯1

道歉的模糊性,通過網頁我的意思是獨立的瀏覽器窗口或標籤即window.open

+0

據我所知,這不是真的有可能。您必須訂閱每個「響應」新數據的組件中的observable,否則他們不會知道發生了變化。所以(如果我正在閱讀這個權利),你做得對。你能澄清它在做什麼是不可取的嗎?我無法從你原來的帖子中辨認出來。 – joshrathke

+0

我想我不明白的部分是「多頁」。在Angular上下文中,這有點令人困惑。你是指應用程序中的多個組件? – joshrathke

+0

當然,基本上我想以某種方式擴展跨多個頁面的服務和排放,而不僅僅是同一頁面中的多個組件。即使我創建了提供程序的單個實例,但該實例僅適用於該頁面內的子組件。然後每個頁面都有它自己的父級實例(因此它贏得了訂戶)。所以想知道如何在多個頁面上創建一個全局實例,如果不可能的話,可能會有什麼樣的解決方法或人們可能已經完成了。 – Googs

回答

1

以防萬一其他人有這個相同的問題 - 事實上有一個答案。 使用全局存儲事件可以跨所有瀏覽器選項卡/窗口遍歷信息。

在服務而不是使用BehaviourSubject,服務更新或'發射'數據到本地存儲項目,使用裝飾器的事件偵聽器可以偵聽這些udpates - 偵聽所有窗口和選項卡。

例子:

@HostListener('window:storage', ['$event']) 
    onStorageChange(ev: StorageEvent) { 
     console.log(ev.key); 
     console.log(ev.newValue);   
    } 

在這裏看到更多的信息:Storage events

+0

哇,很好的發現。這絕對是我的新信息!感謝您花時間更新答案。 – joshrathke

0

所以有在這裏玩幾件事情。首先是讓應用程序知道是時候顯示警報了。這聽起來像你已經有了,但爲了簡單起見,我會確保你在forRoot()上下文中聲明。關於這個話題,我不會深入探討一些細節,但基本上你需要確保你的服務在根環境中運行。如果您啓動延遲加載模塊,然後從延遲加載的模塊中訂閱您的服務,它將創建它自己的依賴注入上下文,並且您將開始抨擊您的表頭,想知道爲什麼您的服務沒有更新。 (在那裏:)

接下來要看的是你想要呈現你的警報。您可能需要使用ComponentFactoryResolver來呈現您認爲合理的最高級別組件中的警報。基本上(如果我理解你的需求是正確的),你需要它在同一個組件內,或者更高的頁面你想要提醒警報的所有頁面。例如,我正在研究一個具有儀表板的應用程序,其中我們有一個ComponentFactoryResolver,用於呈現整個應用程序中可能需要的任何和所有模態。這使我們可以使用與您一樣的行爲主題來激活模態,從儀表板內的任何位置調用模態。 Here's a great article使用ComponentFactoryResolver

更新1 所以,在意識到「頁面」實際上是一個新的瀏覽器窗口後,這種方法不一定會奏效。使用BehaviorSubjects只會在應用程序上下文中更新,因此打開一個新窗口會創建一個新的應用程序上下文,即將其作爲一個可行的候選人來完成此項工作。你需要有一個不是特定於實例的服務。你提到的網絡套接字將是一個很好的選擇。

值得注意的是,如果可以重構代碼以打開模式而不是新窗口,則可以維護依賴注入樹的完整性,然後使用BehaviorSubjects實現此目的。否則,您將需要維護狀態的應用程序之外的某些內容。

+0

我想我有一個問題是你說的「頁面」在多個瀏覽器同時打開的意義上?我仍然不確定什麼是「頁面」。 – joshrathke

+0

因此儀表板中有一個記錄列表,點擊其中一個打開一個新窗口(例如打開患者的醫療列表),打開該特定記錄的患者組件(每個記錄在單獨的窗口中打開)。可以從這些患者窗口中的任何一個窗口提交功能,並且一旦完成,警報不僅應該顯示在儀表板上,還應該顯示發送請求的記錄窗口,但也包括所有其他打開的記錄窗口。希望清除它:) – Googs

+0

所以基本上我的頁面我的意思是瀏覽器窗口,即'window.open' – Googs