ember.js 使用ember简单身份验证进行身份验证后加载用户

4nkexdtk  于 2022-11-05  发布在  其他
关注(0)|答案(2)|浏览(209)

我使用ember simple auth来验证我的用户。它工作得很好,除了当用户刚刚登录时。
我有一个帮助程序,它询问当前用户:

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();期间,helper被执行,它结束运行sessionAuthenticated
发生的情况是,我想要的用户属性是未定义的,这使得它不可能根据用户的角色显示界面元素。
如何解决此问题?
编辑相关问题:如何在模板中使用简单的身份验证来确定用户是否应该看到界面的某个部分?例如菜单选择。

mwg9r5ms

mwg9r5ms1#

您的方法的问题在于helper是同步执行的,而不是以一种重新计算的方式“监视”currentUser服务。使用计算属性来做您想要做的事情要容易得多:

控制器/应用程序.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
  })

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

应用程序.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);
  }
});

然后像这样使用它:

应用程序.hbs

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

thigvfpy2#

首先,我建议不要将currentUser服务传递给helper,如果您将它注入到服务中的话。
接下来,您可以让帮助程序在加载用户后重新计算:

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.runAfterLoaded.forEach(x => x())添加到current-user服务中的load()函数中的this.set('user', user);之后,并将this.set('runAfterLoaded', [])添加到init挂钩中。
另一种可能性是构建一个mixin,将其添加到AuthenticatedRouteMixin之后的相关路由中,以确保加载当前用户。

相关问题