在我的应用程序localStorage
中,我存储了一个用于身份验证的令牌。如果用户进行完全重新加载,我需要向后端发出请求以验证此令牌并获取用户名。对于所有这些会话,我已经做了一个余烬服务。
我的申请路线如下:
import Ember from 'ember';
export default Ember.Route.extend({
currentSession: Ember.inject.service(),
beforeModel: function(transition) {
if (transition.targetName !== 'login') {
const session = this.get('currentSession');
if (!session.isLoggedIn) {
this.transitionTo('login');
}
}
}
});
在重新加载时,会触发应用程序路由上的beforeModel
方法,我可以从服务中获取isLoggedIn
属性。
在服务中我有一个initializeService
方法,它在init上调用:
import Ember from 'ember';
export default Ember.Service.extend({
store: Ember.inject.service(),
username: '',
isLoggedIn: false,
initializeService: function() {
const token = localStorage.getItem('Token');
if (token) {
const self = this;
this.get('store').findRecord('session', token).then(function(session) {
self.set('username', session.get('username'));
self.set('isLoggedIn', true);
});
}
}.on('init'),
});
这基本上可行,但由于异步请求findReocord
而存在竞争条件。在initializeService
this.get('currentSession');
之前,系统不会调用beforeModel
,当服务请求后端时,beforeModel
会继续。所以if (!session.isLoggedIn)
总是如此。
我尝试使用实例初始化器初始化该服务,但这也不起作用。我想我需要做一些同步findRecord
。
是否有可能同步执行请求或有更好的方法吗?
答案 0 :(得分:1)
在当前会话服务中引入名为loadCurrentUser
的方法,该方法返回Promise,并在beforeModel
中使用then
方法来实现您的逻辑。
示例代码, current-session.js 服务文件
import Ember from 'ember';
export default Ember.Service.extend({
store: Ember.inject.service(),
username: '',
isLoggedIn: false,
init() {
this._super(...arguments);
this.loadCurrentUser(); //if you are not calling loadCurrentUser method then this will ensure username and isLoggedIn set properly
},
loadCurrentUser() {
return new RSVP.Promise((resolve, reject) => {
const token = localStorage.getItem('Token');
if (!isEmpty(token)) {
return this.get('store').findRecord('session', token).then((session) => {
this.set('username', session.get('username'));
this.set('isLoggedIn', true);
resolve();
}, reject);
} else {
resolve();
}
});
}
});
application.js 路径文件
import Ember from 'ember';
export default Ember.Route.extend({
currentSession: Ember.inject.service(),
beforeModel: function(transition){
return this.get('currentSession').loadCurrentUser().then((result) => {
if (transition.targetName !== 'login') {
const session = this.get('currentSession');
if (!session.isLoggedIn) {
this.transitionTo('login');
}
}
}
},
});