【问题标题】:Ember delay controller until authentication completesEmber 延迟控制器,直到身份验证完成
【发布时间】:2015-09-28 02:01:19
【问题描述】:

我有一种情况,我需要获取会话的一些属性,但是我还没有找到成功的解决方案,可以在成功登录后延迟加载路由。

这就是交易 - 当用户登录时,他们会被发送到电话号码路由。应用程序控制器上的 this.get('session.currentUser') 尚未设置。

当我去不同的路线然后回来时,它设置正确。如果登录后我在电话号码路由上然后刷新页面,则电话号码会正确加载,因为初始化程序中的 deferReadiness 和 advanceReadiness 。我无法在登录之前延迟Readiness,因为该应用已经加载并准备就绪。

唯一缺少的部分是用户登录后,它应该加载routes/phone-numbers.js 中的数字,这是粘贴在下面的最后一段代码。但是,myStoreId 未加载,因为尚未设置 session.currentUser

我已经尝试了很多方法来让它发挥作用,并且正在寻找关于最后一部分的一些想法。它是如此接近工作,但只是缺少一小部分。

// initializers/current-user.js
import Ember from 'ember';
import Session from 'simple-auth/session';

export default {
  name: 'current-user',
  before: 'simple-auth',

  initialize: function(container, application) {
    Session.reopen({
      setCurrentUser: function() {
        let appController = container.lookup("controller:application");

        // don't know how to check if the app is already ready
        try{
          application.deferReadiness();
          console.log('deferred');
        }catch(e){}

        if(this.get('isAuthenticated')) {
          console.log('running the isAuthenticated obs');

          let store = container.lookup('store:main');
          let _this = this;

          return store.find('user', 'me').then((user) => {
            // set the current user to be used on the session object
            this.set('currentUser', user);
          }).then(function(){
            // set the store for the current user
            store.find('store', {user: _this.get('currentUser.id')}).then(function(data) {
              _this.set('myStore', data.get('firstObject'));
              application.advanceReadiness();
            });
          })
        }
      }.observes('isAuthenticated')
    });
  }
};

// controllers/application.js
export default Ember.Controller.extend({
  myStore: Ember.computed(function(){
    // return the store object that is associated with the current user
    if(this.get('session.isAuthenticated')){
      if(this.get('session.myStore')){
        return this.get('session.myStore');
      }else{
        console.log(this.get('session.currentUser'));
        // this is where the problem is. The session.currentUser is not populated yet.

        this.get('store').find('store', {user: this.get('session.currentUser.id')}).then(function(data) {
          this.get('session').set('myStore', data.get('firstObject'));
          return this.get('session.myStore');
        });
      }
    }
  }),
});


// routes/phone-numbers.js
export default Ember.Route.extend({
  setupController: function(controller, model){
    this._super(controller, model);
    let myStoreId = this.controllerFor('application').get('myStore.id');

    if(!myStoreId){
      console.log(this.get('session.currentUser'));
      // there is no currentUser set on the session after login
    }else{
      this.store.find('store-phone-number', {'store': myStoreId}).then(function(numbers){
        controller.set('numbers', numbers);
      });
    }
  },
});

【问题讨论】:

    标签: javascript ember.js


    【解决方案1】:

    尝试使用 Promises:

    // controllers/application.js
    export default Ember.Controller.extend({
      myStore: Ember.computed('session.currentUser', function(){
        // return the store object that is associated with the current user
        return new Ember.RSVP.Promise(resolve => {
          if(this.get('session.isAuthenticated')){
            if(this.get('session.myStore')){
              resolve(this.get('session.myStore'));
            } else {
              console.log(this.get('session.currentUser'));
              // this is where the problem is. The session.currentUser is not populated yet.
    
              this.get('store').find('store', {user: this.get('session.currentUser.id')}).then(function(data) {
                this.get('session').set('myStore', data.get('firstObject'));
                resolve(this.get('session.myStore'));
              });
            }
          }
        });
      })
    });
    
    
    // routes/phone-numbers.js
    export default Ember.Route.extend({
      setupController: function(controller, model){
        this._super(controller, model);
        let myStoreId = this.controllerFor('application').get('myStore').then(myStore => {
          let myStoreId = myStore.get('id');
          if(!myStoreId){
            console.log(this.get('session.currentUser'));
            // there is no currentUser set on the session after login
          } else {
            this.store.find('store-phone-number', {'store': myStoreId}).then(function(numbers){
              controller.set('numbers', numbers);
            });
          }
        });
      }
    });
    

    【讨论】:

    • 谢谢,我会玩这个。在这个例子中,promise 中的this.get('session.currentUser.id') 在登录时仍然不可用,并且在刷新/路由时它也没有定义并给出错误
    【解决方案2】:

    Daniel 提出的玩弄承诺的建议让我找到了解决方案。本质上,如果 myStore 尚未设置,我需要返回一个承诺,并且还必须在登录后的第一条路由中考虑这一点。

    export default Ember.Controller.extend({
      myStore: Ember.computed(function(){
        // return the store object that is associated with the current user
        if(this.get('session.isAuthenticated')){
          if(this.get('session.myStore')){
            return this.get('session.myStore');
          }else{
            return new Promise(resolve =>{
              this.get('session').setCurrentUser().then(data => {
                this.get('store').find('store', {user: this.get('session.currentUser.id')}).then(data => {
                  this.get('session').set('myStore', data.get('firstObject'));
                  resolve(this.get('session.myStore'));
                });
              });
            })
          }
        }
      }),
    });
    
    export default Ember.Route.extend({
      setNumbers: function(controller, id){
        this.store.find('store-phone-number', {'store': id}).then(numbers => {
          controller.set('numbers', numbers);
        });
      },
      setupController: function(controller, model){
        this._super(controller, model);
    
        if(this.controllerFor('application').get('myStore.id')){
          let myStoreId = this.controllerFor('application').get('myStore.id')
          this.setNumbers(controller, myStoreId);
        }else{
          let myStore = this.controllerFor('application').get('myStore').then(data => {
            this.setNumbers(controller, data.id);
          });
        }
      },
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-25
      • 2023-04-06
      • 2020-11-05
      • 2020-08-28
      • 1970-01-01
      • 2016-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多