2017-04-11 48 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