【问题标题】:Ember Simple Auth - injecting current user into every routeEmber Simple Auth - 将当前用户注入每条路由
【发布时间】:2015-09-01 13:44:56
【问题描述】:

我正在使用 Ember Simple Auth 构建网站。

我跟随these instructions 尝试将当前用户对象添加到会话中,并且使用了这个稍微修改过的代码:

import Ember from 'ember';
import Session from 'simple-auth/session';

export default {
  name: "current-user",
  before: "simple-auth",
  initialize: function(container) {
    Session.reopen({
      setCurrentUser: function() {
        var accessToken = this.get('secure.token');
        var _this = this;
        if (!Ember.isEmpty(accessToken)) {
          return container.lookup('store:main').find('user', 'me').then(function(user) {
            _this.set('content.currentUser', user);
          });
        }
      }.observes('secure.token'),
      setAccount: function() {
        var _this = this;
        return container.lookup('store:main').find('account', this.get('content.currentUser.account.content.id')).then(function(account) {
          _this.set('content.account', account);
        });
      }.observes('content.currentUser'),
    });
  }
};

但是,使用最新版本的 Ember,我得到以下结果:

弃用:lookup 在注册表中被调用。 initializer API 不再接收容器,您应该使用instanceInitializer 从容器中查找对象。详情请见http://emberjs.com/guides/deprecations#toc_deprecate-access-to-instances-in-initializers

我知道我需要将上述内容拆分为 /app/initializers 和 /app/instance-initializers(根据注释 here),但我不太确定如何去做。

当然,如果有一种更简单/更简洁的方法可以使用户和帐户对象可用于每个路由/模板,我很乐意听到它们 :)

谢谢

【问题讨论】:

    标签: ember.js dependency-injection ember-simple-auth


    【解决方案1】:

    这对我有用:

    • ember-cli:0.2.7(ember:1.12.0,ember-data:1.0.0-beta.18)
    • ember-cli-simple-auth:0.8.0-beta.3

    注意:

    • 灰烬数据:1.13。商店在初始化程序中注册,应该按原样工作
    • ember 数据:1.0.0-beta.19。存储在实例初始化程序中注册,需要进行一些调整

    1) 自定义会话

    //config/environment.js
    ENV['simple-auth'] = {
      session: 'session:custom',
      ...
    }
    
    //app/sessions/custom.js
    import Session from 'simple-auth/session';
    
    export default Session.extend({
    
      // here _store is ember-data store injected by initializer
      // why "_store"? because "store" is already used by simple-auth as localStorage
      // why initializer? I tried 
      // _store: Ember.inject.service('store') and got error
    
      currentUser: function() {
        var userId = this.get('secure.userId');
        if (userId && this.get('isAuthenticated')) {
          return this._store.find('user', userId);
        }
      }.property('secure.userId', 'isAuthenticated')
    
    });
    

    2) 通过初始化程序将存储注入会话(否则 find() 将不起作用)

    //app/initializers/session-store
    export function initialize(container, application) {
      application.inject('session:custom', '_store', 'store:main')
    
      // "store:main" is highly dynamic depepeding on ember-data version
      // in 1.0.0-beta.19 (June 5, 2015) => "store:application"
      // in 1.13 (June 16, 2015) => "service:store"
    }
    
    export default {
      name: 'session-store',
      after: 'ember-data',
      initialize: initialize
    }
    

    3) 在模板中

    {{#if session.isAuthenticated}}
      {{session.currentUser.name}}
    {{/if}}
    

    注意:这并不能使您摆脱ember-simple-auth 本身产生的弃用。

    【讨论】:

    • 一个很棒的答案,非常感谢。我必须更新我的自定义 Devise::SessionsController 以返回 userId 以及令牌和电子邮件,但除此之外它完美无缺。
    • Artych,只是一个快速的后续问题 - 我可以使用 this.get('session.currentUser') 访问控制器中的会话对象,但这似乎不适用于路由。我应该做一些不同的事情吗?谢谢
    • 别忘了currentUser 是一个承诺。 this.get('session.currentUser').then(function(user) { console.log('user-name', user.get('name')) }); 适用于每条路线。 (感谢您之前的评论)
    • 您也可以省略初始化器,方法是在 custom.js 中添加:var _store = this.container.lookup('store:application');。如果您的 _store-variable 未定义(错误:“查找未定义”),这也会有所帮助。
    • Ember: 2.2.0Ember Data: 2.2.1Ember Simple Auth: 1.0.0 上尝试过,但没有成功。
    【解决方案2】:

    首先,您不应重新打开会话,而应使用自定义会话(请参阅此示例:https://github.com/simplabs/ember-simple-auth/blob/master/examples/4-authenticated-account.html#L132)。此外,您不仅应该在设置访问令牌时加载当前用户,还应该在会话经过身份验证 ('session.get('isAuthenticated')') 时加载,这会使您的代码不依赖于身份验证器。

    有关在初始化程序中使用注册表的弃用警告有望在 ESA 0.9.0 中消失。

    【讨论】:

    【解决方案3】:

    这是我前几天做的初始化器/实例初始化器的前后对比。

    之前

    export function initialize( container, application ) {
        var session = Ember.Object.create({
            user:null,
            authorization:null
        });
    
        application.register('session:main', session, { instantiate: false });
        application.inject('route', 'session', 'session:main');
        application.inject('controller', 'session', 'session:main');
        application.inject('adapter', 'session', 'session:main');
    }
    

    之后

    export function initialize( instance) {
        var session = Ember.Object.create({
            user:null,
            authorization:null
        });
    
        instance.registry.register('session:main', session, { instantiate: false });
        instance.registry.injection('route', 'session', 'session:main');
        instance.registry.injection('controller', 'session', 'session:main');
        instance.registry.injection('adapter', 'session', 'session:main');
    }
    

    Ember 数据资料

    应使用 store:application 获取最新迭代中的 Ember 数据

    export function initialize(instance) {
        var store = instance.container.lookup('store:application');
        ....
    }
    
    export default {
        name: 'socket',
        initialize: initialize,
        after:['ember-data']
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-26
      相关资源
      最近更新 更多