简体   繁体   English

在路由转换时重新创建Ember.js服务对象

[英]Ember.js Service objects recreated on route transition

As I understand from the documentation a Service is basically a singleton object used to provide services to other objects through the application lifecycle. 从文档中了解到,服务基本上是一个单例对象,用于在应用程序生命周期内向其他对象提供服务。 I have a user management service which I use to save an authentication token after the user logs in using the route /users/login . 我有一个用户管理服务,用于在用户使用/users/login路径/users/login后保存身份验证令牌。 But transitioning to another route ( /composer for instance) causes the service instance to be recreated and hence it loses all the stored data. 但是过渡到另一个路由(例如/composer )会导致重新创建服务实例,因此会丢失所有存储的数据。 Doesn't this contradict the fact that it should live as long as the application does or do I have a wrong of idea this whole lifecycle thingy? 这是否与应用程序可以使用一样长的事实并不矛盾,或者我对整个生命周期的想法都不对吗?

I'm injecting the service in all my routes as below: 我将在所有路线中注入该服务,如下所示:

authenticationService: Ember.inject.service('authentication-service'),

The service itself is only a set of getters and setters: 服务本身只是一组获取器和设置器:

import Ember from 'ember';

export default Ember.Service.extend({
    currentUser: undefined,
    jwtToken: undefined,
    // ================================================================================================================ \\
    // ================================================================================================================ \\
    // ================================================================================================================ \\
    setCurrentUser(user) {
        this.currentUser = user ;
    },
    getCurrentUser() {
        return this.currentUser ;
    },
    isLoggedIn() {
        return Boolean(this.currentUser) ;
    },
    getJwtToken() {
        return this.jwtToken ? this.jwtToken : '' ;
    },
    setJwtToken(jwtToken) {
        this.jwtToken = jwtToken ;
    }
});

Here is how the login token is handled: 这是处理登录令牌的方式:

actions: {
    onSubmitLoginForm() {
        if (!this.validateLoginForm()) {
            return ;
        }
        var self = this ;
        Ember.$.post('login/', {
            'username': this.controller.get('username'),
            'password': this.controller.get('password'),
            'email':    this.controller.get('email'),
        }, function(data) {
            console.log(data) ;
            if (data['success'] === 'Ok') {
                self.get('authenticationService').setJwtToken(data['auth']['jwt']) ;
                var user = self.get('store').createRecord('user', {
                    username: data['auth']['user']['username'],
                    email   : data['auth']['user']['email'],
                    mongoId : data['auth']['user']['id']['$oid'],
                }) ;
                self.get('authenticationService').setCurrentUser(user) ;
                self.transitionTo('home') ;
                console.log('logged in') ;
                console.log(self.get('authenticationService').getJwtToken()) ;
                console.log(self.get('authenticationService').getCurrentUser()) ;
                console.log(self.get('authenticationService').isLoggedIn()) ;
            } else {
                self.transitionTo('error') ;
            }
        }) ;
    },
}

I'm not looking for suggestions on using some other means of persistence such as IndexedDB; 我不是在寻找使用其他持久性手段(例如IndexedDB)的建议; I'm willing to understand how this thing actually works so any explanation is appreciated. 我愿意了解这件事的实际运作方式,因此欢迎您提供任何解释。

Yes, you understand it right - service is a singletone and I can assure you that service persists its state between trasitions. 是的,您没看错-服务是单调的,我可以向您保证服务在两次转换之间保持其状态。 But to make a transition, you must use link-to helper. 但是要进行过渡,您必须使用link-to帮助器。 If you are changing url manually, you reloading your app instead of transitioning. 如果您要手动更改url,则可以重新加载应用程序,而不进行过渡。 And app reload of course causes state reset. 当然,应用程序重新加载会导致状态重置。 You should use any available kind of storage to persist state between page reloads. 您应该使用任何可用的存储方式在页面重新加载之间保持状态。 It may be local storage, session storage, cookies etc. 它可能是本地存储,会话存储,Cookie等。

Also, in Ember we don't use such code: this.currentUser = user ; 另外,在Ember中,我们不使用这样的代码: this.currentUser = user ; on Ember objects. 在灰烬的物体上。 We use this.set('currentUser', user); 我们使用this.set('currentUser', user); instead. 代替。 Otherwise Ember would not be able to rerender templates, update computed properties and work properly. 否则,Ember将无法重新渲染模板,更新计算的属性并无法正常工作。

And finally, you shouldn't build auth solution from zero. 最后,您不应该从零开始构建身份验证解决方案。 It's very hard and complex thing to do. 这是非常困难和复杂的事情。 Instead, you can use ember-simple-auth addon and build authentication process on top of it. 相反,您可以使用ember-simple-auth插件,并在其之上构建认证过程。 It will be much easier and result will be more reliable. 这样会更容易,结果也会更可靠。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM