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

时间:2017-06-16 20:12:57

标签: ember.js ember-data

据我从文档中了解,Service基本上是一个单例对象,用于通过应用程序生命周期为其他对象提供服务。我有一个用户管理服务,用于在用户使用路由/users/login登录后保存身份验证令牌。但转换到另一个路由(例如/composer)会导致重新创建服务实例,因此会丢失所有存储的数据。这不是一个事实,它应该只要应用程序存在就可以存在,或者在整个生命周期中我是否有错误的想法?

我在所有路线中注入服务,如下所示:

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

服务本身只是一组getter和setter:

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

以下是处理登录令牌的方法:

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') ;
            }
        }) ;
    },
}

我没有寻找使用其他一些持久性方法的建议,例如IndexedDB;我很乐意了解这件事是如何运作的,所以任何解释都会受到赞赏。

1 个答案:

答案 0 :(得分:2)

是的,你理解正确 - 服务是一个单一的,我可以向你保证,服务在传统之间保持其状态。但要进行转换,您必须使用link-to帮助程序。如果您手动更改网址,则会重新加载应用而不是转换。 app重新加载当然会导致状态重置。您应该使用任何可用类型的存储来在页面重新加载之间保持状态。它可能是本地存储,会话存储,cookie等。

此外,在Ember中,我们不会在Ember对象上使用此类代码:this.currentUser = user ;。我们改用this.set('currentUser', user);。否则,Ember将无法重新呈现模板,更新计算属性并正常工作。

最后,你不应该从零构建auth解决方案。这是非常困难和复杂的事情。相反,您可以使用ember-simple-auth插件并在其上构建身份验证过程。它会更容易,结果会更可靠。