Dependency injection Aurelia单体视图模型

Dependency injection Aurelia单体视图模型,dependency-injection,singleton,containers,aurelia,Dependency Injection,Singleton,Containers,Aurelia,在Aurelia项目中,我有一个视图模型,我希望在路由器导航之间保持状态。我认为将@singleton()添加到视图模型类中可以实现这一点 事实上,我已经创建了一个简单的Aurelia项目。我能够从同一页面来回导航,并且状态保持不变。我的构造函数只有在我第一次导航到该页面时才被调用 import { singleton } from 'aurelia-framework'; @singleton() export class Welcome { heading = 'Welcome to

在Aurelia项目中,我有一个视图模型,我希望在路由器导航之间保持状态。我认为将
@singleton()
添加到视图模型类中可以实现这一点

事实上,我已经创建了一个简单的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');
  }
}
但是,在我的大型应用程序中,这不起作用。我添加了decorator,第二次导航到该页面时,视图模型的构造函数仍然被调用。(我甚至将这个视图模型复制到了我的更大的应用程序中,它并没有被视为一个单例。)


显然,这两个项目之间肯定有一些不同之处。然而,我看不出有什么不同。我是否设置了一个可以覆盖
@singleton()
行为的设置

您可能有多个singleton自定义元素的实例-根据定义,singleton本身不能有多个实例。您需要的是一个只创建一次并重用的视图模型

这是一个我成功使用的解决方案。其思想是拥有一个一次性构造的全局视图模型实例,并且有一个控制器视图使用它来组成视图/虚拟机

HTML

您在这个视图模型中所做的一切现在都将在导航之间保持,并且构造函数只会被调用一次。singleton视图模型的attached()和Distached()仍将按预期激活


还请注意,您可以使用它缓存视图模型的多个实例,以便在这些模型之间切换。我的应用程序有一个全局服务来跟踪多个VM,这些VM根据请求构造/返回VM。这带来的好处是,我可以在构造函数阶段完成一次繁重的处理,然后再也不用担心了

原来解决方案是jspm更新。我曾认为删除我的jspm_包和运行jspm安装是等效的。但事实并非如此

既然我的Aurelia模块是最新的,singleton()装饰器就可以正常工作了

<template>
  <require from="yourView.html"></require>
  <p> parentClass.html </p>
  <compose view="yourView.html" view-model.bind="singletonViewModel"></compose>
</template>
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;
  }
}