2017-06-16 69 views
0

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

我注射服务在我所有的路线如下:

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

我不是在寻找建议使用一些其他方式的持久性,如在dexedDB;我很乐意了解这件事实际上是如何运作的,所以任何解释都会被赞赏。

+0

你的理解一般是正确的。这是您的服务还是来自附加组件?你如何检测到服务正在被实例化?你过得怎么样? – mwp

+1

在您的服务方法中,您应该使用'get'和'set'来获取和设置属性。不幸的是,仅仅因为属性是“本地”并不意味着你可以避免这种情况。也许更新这些方法,看看你的问题是否仍然存在? – mwp

+0

@mwp试过了,没有帮助。无论如何,我不认为它在这里是必要的,因为Ember.Object的get和set方法是为了数据绑定和我们在此不使用的观察者。 – DarthPaghius

回答

2

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

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

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

+0

关键是使用'{{link-to}}'。好像我在应用程序的某些地方习惯了习惯使用html锚定标记。关于你的其他建议我相信,只要满足确切的要求,使用和插件就是一件好事,否则它将是一个修改它的折磨过程。感谢您的回答。 – DarthPaghius