2016-11-30 4 views
2

In meiner App localStorage Ich habe ein Token für Auth gespeichert. Wenn der Benutzer ein vollständiges Neuladen durchführt, muss ich eine Anfrage an das Backend stellen, um dieses Token zu überprüfen und den Benutzernamen zu erhalten. Für all diese Session-Sachen habe ich einen Glut-Service gemacht. Meine Anwendung Route wie folgt aussieht:Anfrage in Ember vor dem Rendern einer Route

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

Auf nachladen beforeModel Methode zur Anwendung Route ausgelöst wird, und ich kann die isLoggedIn Eigenschaft aus dem Service.

Im Dienst Ich habe eine initializeService Methode, die auf init aufgerufen wird:

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

Dies funktioniert im Prinzip, aber es gibt eine Race-Bedingung wegen der Asynchron-Anfrage findReocord. initializeService wird nicht bis this.get('currentSession'); in beforeModel aufgerufen, und während der Dienst das Back-End anfordert, wird beforeModel fortgesetzt. So ist die if (!session.isLoggedIn) immer wahr. Ich habe versucht, den Dienst früher zu initialisieren, indem ich einen Instanz-Initialisierer verwendete, aber das hat auch nicht funktioniert. Ich denke, ich muss eine Art von synchronen findRecord machen.

Gibt es eine Möglichkeit, eine Anfrage synchron zu machen, oder gibt es einen besseren Weg?

Antwort

1

Einführung Methode loadCurrentUser in der aktuellen Sitzung Dienst mit dem Namen, die Versprechen zurückkehrt und in beforeModel Verwendung then Methode, um Ihre Logik zu implementieren.

Beispielcode, Strom session.js Servicedatei

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 Routendatei

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

vielen Dank, werde ich versuchen, dass so schnell wie möglich –

Verwandte Themen