2017-04-11 83 views
1

我的問題是:當我們在路由器中的視圖之間交換時,是否可以保留路由器視圖的相同視圖模型實例?Aurelia路由 - 防止視圖交換每次實例化新的視圖模型

我解釋我的問題:我想使路由器子組件通信感謝EventAggregator。我的一個路由器子組件發佈消息,點擊一個按鈕,另一個訂閱它。

這裏是訂閱了該事件的組件的代碼:

constructor(private ea: EventAggregator) { 
    ea.subscribe(GameInfo, msg => console.log(msg)); 
} 

當我點擊我的按鈕,我在控制檯多個日誌(或無)看到這取決於時間,我駕駛的數我認爲是訂閱。

這裏是我的路由器組件:

import {Router, RouterConfiguration} from 'aurelia-router'; 

export class Playground { 
    public router: Router; 

    public configureRouter(config: RouterConfiguration, router: Router) { 
    config.map([ 
     { route: ['', 'media-creator'], name: 'media-creator', moduleId: './media-creator/media-creator', nav: true, title: 'Media Creator' }, 
     { route: 'board-initializer', name: 'board-initializer', moduleId: './board-initializer/board-initializer', nav: true, title: 'Board Initializer' }, 
     { route: 'code-editor', name: 'code-editor', moduleId: './code-editor/code-editor', nav: true, title: 'Code Editor' } 
    ]); 

    this.router = router; 
    } 
} 

我想從董事會初始化程序的代碼編輯器發送信息,我需要保持各個組件的狀態,當我瀏覽通過路由器。


也許這是不可能的,以防止這種機制和我的解決辦法是使用一個自舉導航的選項卡/數據切換。

謝謝您對任何給定的見解。

+0

所以這裏的實際問題是,您從同一視圖模型獲得多個事件偵聽器? – Tom

+0

@thebluefox我認爲問題在於,我每次導航到我的視圖時都會調用構造函數,並且我多次訂閱相同的事件。另一個原因是我想在導航時保持模型視圖處於相同的狀態(至少是BoardInitializer組件),所以用戶不會失去他在該視圖中所做的。 – SimonC

+0

嗨@SimonC,有bluefox回答你的問題?如果沒有,我很樂意進一步幫助,只是讓我們知道你需要澄清。如果您的問題得到解答,請標記接受的答案。謝謝! – thinkOfaNumber

回答

2

首先,關於多次添加Event Listener的問題 - 您需要改變添加方式,然後確保在當前虛擬機分離時將其刪除。

下面,我已經從優秀的ILikeKillNerds.com博客的代碼 - 這是一個老實說救護員有時。

https://ilikekillnerds.com/2016/02/working-with-the-aurelia-event-aggregator/

import { inject } from 'aurelia-framework'; 
import { EventAggregator } from 'aurelia-event-aggregator'; 

@inject(EventAggregator) 
export class MyClass { 
    constructor(EventAggregator) { 
     this.ea = EventAggregator; 
    } 

    attached() { 
     this.subscriber = this.ea.subscribe('puppyMonkeyBaby', response => { 
      console.log(response.testValue); 
     }); 
    } 

    detached() { 
     this.subscriber.dispose(); 
    } 
} 

正如你可以看到,事件偵聽器在attached()方法加入,然後當上述VM(勿庸置疑)detached()被拆卸重要的去除。

存儲狀態比較困難,因爲Mgiesa已經介紹了幾種不同的方法來處理它,這取決於您的用例。

就個人而言,我會考慮使用一個類作爲單例,它被注入到每個不同的視圖模型中,並允許您共享狀態。

再一次,這是一個很棒的ILikeKillNerds.com,他提供了一個很棒的博客。

https://ilikekillnerds.com/2016/02/shared-state-in-aurelia/

注入視圖模型(不使用NewInstance.of())任何類將被認爲是一個單例。

+0

非常感謝,它真的幫助! – SimonC

1

我已經看到了有關維護狀態,而最近瀏覽了不少問題。視圖模型在不再需要時會被解構,因此您無法使用所顯示的路由器配置從視圖模型本身維護狀態。

你有兩個選擇:

1)注入到服務都需要在該服務中的隊列進行溝通和跟蹤消息的ViewModels的。在您導航時,請檢查隊列並按順序處理消息。不是完美的解決方案,但只要隊列不會變得太大,它就會工作。

2)建立一個單一的路徑和參數添加到代表頁面應該是可見的,然後把兩者的ViewModels在頁面上的組件和show.bind在路線參數的路徑。當你想切換部件還叫router.navigateToRoute(),但指向同一路線(只是改變爲其組件可見參數)。您還需要設置激活策略,以「invokeLifecycle」,使視圖模型的路由器生命週期掛鉤被稱爲和路由參數的值可以被處理。這樣做的好處是,這兩個組件的ViewModels將活路,使他們能夠繼續傳遞消息給對方,並給用戶它,就好像他們在頁面之間進行導航仍然出現。如果你不在意更新URL,那麼你當然可以跳過所有這些,只是在本地跟蹤一個變量。

我可以寫出來的代碼示例時,我要在電腦

作爲一個側面說明,請不要將訂閱事件聚集在構造函數因爲你已經注意到了,你會得到多個預訂。訂閱激活或附加,然後取消訂閱停用或分離。

+0

太棒了!非常感謝你。我會嘗試設置你的第二個選項,這似乎很適合我的需求。 因爲我是aurelia的新手,如果很高興看到代碼示例:)。 – SimonC