【问题标题】:User loading after authentication with ember simple auth使用 ember simple auth 进行身份验证后加载用户
【发布时间】:2020-02-19 22:58:48
【问题描述】:

我使用 ember 简单身份验证来验证我的用户。 除非用户刚刚登录,否则它工作得非常好。

我有一个助手询问当前用户:

import Helper from '@ember/component/helper';
import { inject as service } from '@ember/service';

export default Helper.extend({
  currentUser: service('current-user'),
  compute([feature,currentUser]) {
    let role = currentUser.get('user.role')

Helper 用在模板嵌入到 application.hbs 中的模板中

{{#if (permission-for "users" currentUser)}}
  <li>{{#link-to 'users'}}<i class="fa fa-user"></i> <span>Clients</span>{{/link-to}}</li>
  {{/if}}

当前的用户服务与文档中的这个重复:https://github.com/simplabs/ember-simple-auth/blob/master/guides/managing-current-user.md#loading-the-user-with-its-id

我的 application.js 也在使用同一指南中的代码。

根据我的尝试,sessionAuthenticated 开始运行,在await this._loadCurrentUser(); 期间执行助手,并完成运行sessionAuthenticated

我想要的用户属性未定义,导致无法根据用户的角色显示界面元素。

我该如何解决这个问题?

编辑相关问题:如何在模板中使用 ember simple auth 来确定用户是否应该看到界面的某些部分?例如菜单选择。

【问题讨论】:

  • 你是如何使用助手的?
  • 编辑了问题

标签: ember.js ember-simple-auth


【解决方案1】:

您的方法的问题是助手正在同步执行,并且没有以重新计算的方式“监视”currentUser 服务。使用计算属性来做你想做的事情会容易得多:

controllers/application.js

  currentUser: service(),

  hasPermissionForUsers: computed("currentUser.user", function() {
    const user = this.get("currentUser.user");

    if (! user) return false;

    return user.get("role") === "users"; // taking a random guess at what your helper does here
  })

一旦加载用户,此属性现在将重新计算:

application.hbs

  {{#if hasPermissionForUsers}}
    <li>{{#link-to 'users'}}<i class="fa fa-user"></i> <span>Clients</span>{{/link-to}}</li>
  {{/if}}

如果你必须使用助手,它是可行的,但它并不漂亮。它不那么优雅的原因是助手无法访问相同的上下文,因此重新计算更加困难。你可以这样做:

import Helper from '@ember/component/helper';
import { inject as service } from '@ember/service';
import { run } from '@ember/runloop';
import { addObserver, removeObserver } from '@ember/object/observers';

export default Helper.extend({

  currentUser: service(),

  willDestroy() {
    this._super(...arguments);
    const container = this.get('_container');
    removeObserver(container, 'currentUser.user', this, this.update);
  },

  compute([feature, container]) {
    addObserver(container, 'currentUser.user', this, this.update);
    this.set('_container', container); // used for cleanup

    const user = this.get('currentUser.user');

    if (! user) return false;

    return user.get('role') === feature;
  },

  update() {
    run.once(this, this.recompute);
  }
});

然后像这样使用它:

application.hbs

{{#if (permission-for "users" this)}}
  <li>{{#link-to 'users'}}<i class="fa fa-user"></i> <span>Clients</span>{{/link-to}}</li>
{{/if}}

【讨论】:

    【解决方案2】:

    首先,如果您将 currentUser 服务注入到服务中,我建议不要将其传递给助手。

    接下来你可以让助手在加载用户后重新计算:

    export default Helper.extend({
      currentUser: service('current-user'),
      init() {
        if(!this.currentUser.user) {
          this.currentUser.runAfterLoaded.push(() => this.recompute());
        }
      },
      compute([feature]) {
        if(!this.currentUser.user)
          return false;
        }
        let role = this.currentUser.get('user.role')
        ...
        return ..;
      }
    });
    

    您还需要在this.set('user', user); 之后将this.runAfterLoaded.forEach(x =&gt; x()) 添加到current-user 服务中的load() 函数,并将this.set('runAfterLoaded', []) 添加到init 挂钩。


    另一种可能性是构建一个 mixin,将其添加到 AuthenticatedRouteMixin 之后的相关路由中,以确保加载当前用户。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-24
      • 1970-01-01
      • 2015-04-16
      • 2017-07-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多