2017-04-11 5 views
1

私の質問は:ルータのビュー間を入れ替えると、ルータビューの同じビューモデルインスタンスを維持できますか?Aureliaルーティング - 毎回新しいビューモデルをインスタンス化するのを防ぐ

私は私の問題について説明します:EventAggregatorのおかげで、ルータの子コンポーネントが通信できるようにしたいと思います。私のルータ - 子コンポーネントの1つは、ボタンをクリックしてメッセージを公開し、もう1人がそれを購読します。ここで

は、そのイベントをサブスクライブコンポーネントのコードです:

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

私は私のボタンをクリックすると、私はコンソール複数のログ(またはnone)で見る私はナビゲート時間の数に応じて、私の意見には購読しています。ここで

は、私のルータコンポーネントです:

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

私はコードエディタにボード初期化子からの情報を送信したいのですが、私はルータをナビゲートしていたとき、私は、各コンポーネントの状態を維持する必要があります。


おそらく、このメカニズムを防ぐことはできません。私の解決策は、ブートストラップnav-tabs/data-toggleを使用することです。

ありがとうございました。

+0

実際の問題は、同じView Modelから複数のイベントリスナーを取得することです。 – Tom

+0

@thebluefox私の問題は、私のビューに移動するたびに私のコンストラクタが呼び出され、同じイベントに複数回サブスクライブすることだと思います。もう1つは、私が(少なくともBoardInitializerコンポーネントのために)ナビゲートしているときと同じ状態にモデルビューを保持したいので、ユーザーはそのビューで行ったことを失わないということです。 – SimonC

+0

こんにちは@SimonC、thebluefoxさんがあなたの質問に答えましたか?そうでない場合、私はさらに助けてくれることを嬉しく思っています。あなたの質問に答えるなら、受け入れられた答えに印を付けてください。ありがとう! – thinkOfaNumber

答えて

2

まず、イベントリスナーの問題を複数回追加します。追加する方法を変更し、現在のVMが取り外されたときに削除する必要があります。

以下、優れた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つのオプションがあります。移動するときは、キューをチェックし、メッセージを順番に処理してください。完璧な解決策ではありませんが、キューがあまり大きくならない限り機能します。

2)ルートを1つ作成し、どのページを表示するかを表すパラメータをルートに追加し、両方のビューモデルをコンポーネントとしてページに配置し、ルートパラメータにshow.bindを配置します。コンポーネントを切り替えたい場合でも、router.navigateToRoute()を呼び出しますが、同じルートをポイントします(コンポーネントが表示されるパラメータを変更するだけです)。また、アクティブ化戦略を "invokeLifecycle"に設定して、ビューモデルのルータライフサイクルフックが呼び出され、ルートパラメータの値が処理されるようにする必要があります。ここでのメリットは、2つのコンポーネントのビューモデルが存続し、メッセージを互いに引き続き渡すことができること、そしてページ間を移動しているかのように表示されるユーザーにメッセージを渡すことができることです。 URLを更新する気にならない場合は、もちろんこれをすべてスキップして、ローカル変数を追跡することもできます。

私はサイドノートとしてコンピュータ

に到達したときに気づいたとして、あなたが複数のサブスクリプションを取得しますので、私は、コンストラクタ内のイベントアグリゲータに加入していない、コードサンプルを書き出すことができます。サブスクリプションをアクティブにするか、アタッチしてからサブスクライブを解除するか、または非アクティブにする。

+0

驚くばかりの答え!どうもありがとうございました。私はあなたのニーズにうまく収まるような、2番目のオプションを設定しようとします。 私はaureliaを初めて使っているので、コードサンプルを見ることができれば嬉しいです:)。 – SimonC

関連する問題