You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于ESA隐式授权认证,如何为已认证用户加载应用模板店铺模型数据

实现认证后加载店铺数据到导航栏的方案

既然你已经搞定了隐式授权,并且导航栏的认证判断逻辑也写好了,接下来只需要把店铺数据的加载和模板渲染串联起来就行,下面是具体的实现步骤:

1. 在Application路由中处理数据加载

因为导航栏属于Application模板,对应的application.js路由是加载全局数据的最佳位置——它是所有路由的父路由,会在应用启动时执行,而且能方便地结合会话状态控制数据加载。

修改你的app/routes/application.js:

import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

export default class ApplicationRoute extends Route {
  @service session; // 注入会话服务
  @service store; // 注入数据仓库服务

  async model() {
    // 仅当用户已认证时,加载所有店铺数据
    if (this.session.isAuthenticated) {
      return this.store.findAll('shop'); // 这里的`shop`是你的数据模型名称,按需修改
    }
    // 未认证时返回空数组,避免模板报错
    return [];
  }
}

2. 在Application模板中渲染店铺列表

在你已经写好的{{#if session.isAuthenticated}}代码块里,遍历路由返回的模型数据即可:

{{!-- app/templates/application.hbs --}}
{{#if session.isAuthenticated}}
  <li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
      我的店铺
    </a>
    <ul class="dropdown-menu">
      {{!-- 遍历路由传递的模型数据 --}}
      {{#each @model as |shop|}}
        <li><a class="dropdown-item" href={{route 'shops.show' shop}}>{{shop.name}}</a></li>
      {{else}}
        <li><span class="dropdown-item-text">暂无可用店铺</span></li>
      {{/each}}
    </ul>
  </li>
{{/if}}

3. 处理认证状态动态变化的场景

上面的代码能解决应用启动时已认证用户的店铺加载,但如果用户是在应用运行过程中登录的(比如从登录页跳转回来),session的isAuthenticated状态变化后,需要重新触发数据加载。可以在路由里监听会话的认证成功事件:

更新app/routes/application.js:

import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { scheduleOnce } from '@ember/runloop';

export default class ApplicationRoute extends Route {
  @service session;
  @service store;

  init() {
    super.init(...arguments);
    // 监听登录成功事件,刷新路由重新加载数据
    this.session.on('authenticationSucceeded', () => {
      scheduleOnce('afterRender', this, () => {
        this.refresh(); // 调用refresh会重新执行model钩子
      });
    });
  }

  async model() {
    if (this.session.isAuthenticated) {
      return this.store.findAll('shop');
    }
    return [];
  }

  willDestroy() {
    super.willDestroy(...arguments);
    // 移除事件监听,避免内存泄漏
    this.session.off('authenticationSucceeded');
  }
}

可选:用Controller管理数据(更灵活的方式)

如果需要更精细地控制数据的加载状态(比如显示加载中提示),或者后续要做数据更新,可以把数据逻辑放到Application控制器里:

控制器代码

// app/controllers/application.js
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
import { task } from 'ember-concurrency';

export default class ApplicationController extends Controller {
  @service session;
  @service store;
  @tracked shops = []; // 用tracked标记,自动响应数据变化

  constructor() {
    super(...arguments);
    // 监听登录/登出事件,更新数据
    this.session.on('authenticationSucceeded', () => this.loadShops.perform());
    this.session.on('invalidationSucceeded', () => this.shops = []);
  }

  // 用ember-concurrency的task处理异步加载,自带加载状态
  @task *loadShops() {
    if (this.session.isAuthenticated) {
      this.shops = yield this.store.findAll('shop');
    }
  }

  init() {
    super.init(...arguments);
    // 应用启动时如果已认证,直接加载数据
    if (this.session.isAuthenticated) {
      this.loadShops.perform();
    }
  }

  willDestroy() {
    super.willDestroy(...arguments);
    // 清理事件监听
    this.session.off('authenticationSucceeded');
    this.session.off('invalidationSucceeded');
  }
}

对应模板修改

{{!-- app/templates/application.hbs --}}
{{#if session.isAuthenticated}}
  <li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
      我的店铺
    </a>
    <ul class="dropdown-menu">
      {{#if this.loadShops.isRunning}}
        <li><span class="dropdown-item-text">加载中...</span></li>
      {{else}}
        {{#each this.shops as |shop|}}
          <li><a class="dropdown-item" href={{route 'shops.show' shop}}>{{shop.name}}</a></li>
        {{else}}
          <li><span class="dropdown-item-text">暂无可用店铺</span></li>
        {{/each}}
      {{/if}}
    </ul>
  </li>
{{/if}}

内容的提问来源于stack exchange,提问作者belgoros

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:45:01