2017-02-21 5 views
3

Aureliaプロジェクトでは、ルータのナビゲーションの間に状態を維持したいビューモデルがあります。私は@singleton()を私のビューモデルクラスに加えるとこれを達成すると思った。Aurelia Singleton Viewモデル

実際、私はこれが機能する簡単なAureliaプロジェクトを作成しました。私は同じページに戻ったり離れたりすることができ、状態は維持されます。私のコンストラクタは、初めてそのページに移動するときに呼び出されます。

import { singleton } from 'aurelia-framework'; 

@singleton() 
export class Welcome { 
    heading = 'Welcome to the Aurelia Navigation App!'; 

    constructor() { 
     console.log('constructor'); 
    } 

    activate() { 
     console.log('activate'); 
    } 

    attached() { 
     console.log('attached'); 
    } 
} 

しかし、私の大きなアプリケーションでは、これは機能しません。デコレータを追加して、ビューモデルのコンストラクタを2回目に呼び出すと、そのページに移動します。 (私はこのビューモデルを私の大きなアプリケーションにコピーしたこともあり、シングルトンとしては扱われません)

明らかに、これらの2つのプロジェクトでは、何かが異なる必要があります。しかし、私は違いは見ません。 @singleton()の動作を上書きする設定がありますか?

+2

https://github.com/aurelia/dependency-injection/issues/65 –

答えて

1

シングルトンのカスタム要素のインスタンスが複数ある可能性があります。シングルトンの定義では、複数のインスタンスを定義することはできません。あなたが望むのは、一度作成され再利用されるビューモデルです。

ここで私が成功裏に使用した解決策があります。このアイデアは、一度構築されたグローバルビューモデルインスタンスを持つことであり、ビュー/ VMを構成するためにそれを使用するコントローラビューがあります。このビューモデル内で行う

HTML

<template> 
    <require from="yourView.html"></require> 
    <p> parentClass.html </p> 
    <compose view="yourView.html" view-model.bind="singletonViewModel"></compose> 
</template> 

JS

import { YourView } from 'yourView'; 
export class parentClass { 
    // constructor for parentClass will run multiple times. 
    constructor() { 
    /** this is the key, you must instantiate a custom view model once 
    on some globally singleton object like window or global in Node */ 
    if (typeof window.yourView === 'undefined') { 
     window.yourView = new YourView(); 
    } 
    } 

    bind() { 
    this.singletonViewModel = window.yourView; 
    } 
} 

すべてが一度だけ呼び出されますナビゲーションとコンストラクタの間で今、持続します。シングルトンビューモデルのattached()およびdetached()は、期待どおりにアクティブになります。

また、これを使用して、切り替えが可能なビューモデルの複数のインスタンスをキャッシュすることができます。私のアプリケーションには、要求に応じてVMを構築/返す複数のVMを追跡するグローバルサービスがあります。この利点は、コンストラクターステージで重い処理を1回行うことができ、それをもう一度心配することがないということです。

1

それは解決策がjspmアップデートになったことが判明しました。私は自分のjspm_packagesを削除してjspm installを実行することは同等であると思っていました。そうではありません。

私のAureliaモジュールは最新ですので、シングルトン()デコレータはうまく動作します。