簡體   English   中英

Angular 2 - 跨多個瀏覽器窗口的單一服務提供商

[英]Angular 2 - single service provider across multiple browser windows

我試圖在任務完成后提供警報 - 用戶當時可能處於多個頁面中的任何一個頁面。 警報應顯示在所有頁面上。

我正在使用一個實現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);

在警報組件中,我訂閱了該事件

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

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

編輯1

對於模糊性的抱歉,頁面我指的是單獨的瀏覽器窗口或選項卡,即window.open

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

在服務中而不是使用BehaviourSubject ,服務將數據更新或“發送”到本地存儲項,使用HostListener()裝飾器的事件偵聽器可以偵聽這些udpates - 它可以偵聽所有窗口和選項卡。

例:

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

有關詳細信息,請參閱此處: 存儲事件

所以這里有幾件事情在發揮作用。 第一個是讓您的應用程序知道是時候顯示警報的服務。 聽起來你已經有了這個,但為了簡單起見,我會確保你在forRoot()上下文中聲明它。 我不會詳細介紹有關此主題的詳細信息,但實質上您需要確保您的服務在根上下文中運行。 如果您開始延遲加載模塊,然后從延遲加載的模塊中訂閱您的服務,它將創建它自己的依賴注入上下文,您將開始在桌子上敲擊您想知道您的服務未更新的原因。 (到過那里 :)

接下來要看的是您要呈現警報的位置。 您可能希望使用ComponentFactoryResolver在您認為合理的最高級別組件中呈現警報。 基本上(如果我理解你的需要正確),你需要將它放在同一個組件中,或者更高,就像你想要提醒警報的所有頁面一樣。 例如,我正在開發一個具有儀表板的應用程序,其中我們有一個ComponentFactoryResolver ,它可以呈現整個應用程序中可能需要的任何和所有模態。 這允許我們使用與您一樣激活模態的行為主題,從儀表板內的任何位置調用模態。 這是一篇關於使用ComponentFactoryResolver 的精彩文章

更新1因此,在意識到“頁面”實際上是一個新的瀏覽器窗口后,此方法不一定有效。 使用BehaviorSubjects只會在應用程序上下文中更新,因此打開一個新窗口會創建一個新的應用程序上下文,即殺死BehaviorSubject成為一個可行的候選者來使其工作。 您需要擁有非特定於實例的服務。 您提到的Web套接字將是一個不錯的選擇。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM