在渲染路线前请求Ember

时间:2016-11-30 12:15:04

标签: javascript ember.js promise

在我的应用程序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

是否有可能同步执行请求或有更好的方法吗?

1 个答案:

答案 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');
              }
            }
        }
    },    
});
相关问题