如何在ExtJS的Application.js中延迟加载Stores以避免401认证错误?
解决ExtJS认证后延迟加载Stores的方案
要解决认证前加载Rest Proxy Stores导致的401错误,我们需要移除Application中预定义的stores数组,改为在认证成功后动态加载并注册这些Stores,同时处理页面刷新时的已登录状态。
1. 修改Application.js,移除预加载的Stores
首先,去掉stores数组,并调整requires避免自动加载Stores类:
Ext.Loader.setConfig({ enabled: true, paths: { 'Ext.ux.exporter': 'exporter', 'Overrides': 'overrides' } }); Ext.define('cardioCatalogQT.Application', { extend: 'Ext.app.Application', name: 'cardioCatalogQT', requires: [ 'Ext.app.*', 'cardioCatalogQT.config.Config', 'Ext.ux.exporter.Exporter', 'Ext.state.CookieProvider', 'Ext.window.MessageBox', 'Ext.tip.QuickTipManager', 'Ext.form.Panel', 'Ext.ux.form.MultiSelect', 'Ext.ux.form.ItemSelector', 'Ext.overrides.selection.CheckboxModel', 'Ext.overrides.view.MultiSelectorSearch', // 仅加载必要的视图/控制器,避免自动加载Stores 'cardioCatalogQT.view.login.Login', 'cardioCatalogQT.view.main.Main', 'cardioCatalogQT.view.login.LoginController' ], // 移除stores数组,不再预加载 init: function() { }, views: [ 'cardioCatalogQT.view.login.Login', 'cardioCatalogQT.view.main.Main' ], launch: function () { Ext.Loader.setConfig({enabled: true}); // 静态配置参数 cardioCatalogQT.config = { protocol: 'http://', host: 'localhost', apiGetQ: '/queryview/api/test', apiWriteQ: '/queryview/api/create', apiReadQ: '/remote_query_get', remove: 'none' }; var loggedIn = localStorage.getItem("CCLoggedIn"); var app = this; if (loggedIn) { // 已登录状态:先加载Stores,再渲染主视图 this.loadRequiredStores(function() { Ext.widget('main-view'); }); } else { // 未登录:显示登录窗口 Ext.widget('login'); } }, // 封装加载Stores的方法,复用逻辑 loadRequiredStores: function(callback) { var requiredStores = [ 'cardioCatalogQT.store.Attributes', 'cardioCatalogQT.store.BasicVitals', 'cardioCatalogQT.store.Diagnoses', 'cardioCatalogQT.store.Labs', 'cardioCatalogQT.store.Procedures', 'cardioCatalogQT.store.Payload', 'cardioCatalogQT.store.Queries', 'cardioCatalogQT.store.Results', 'cardioCatalogQT.store.TestResults', 'cardioCatalogQT.store.Races', 'cardioCatalogQT.store.Ethnicities' ]; // 动态加载Stores类 Ext.require(requiredStores, function() { // 将Stores注册到Application和StoreManager this.addStores(requiredStores); // 执行回调(比如渲染主视图) if (typeof callback === 'function') { callback(); } }, this); } });
2. 在登录成功逻辑中动态加载Stores
修改登录控制器的登录成功处理方法,完成认证后调用Application的loadRequiredStores方法:
Ext.define('cardioCatalogQT.view.login.LoginController', { extend: 'Ext.app.ViewController', alias: 'controller.login', onLoginButtonClick: function() { // 这里是你的认证逻辑(比如AJAX请求验证用户名密码) var authSuccess = true; // 替换为实际认证结果 if (authSuccess) { // 写入LocalStorage标记登录状态 localStorage.setItem("CCLoggedIn", true); // 获取Application实例,加载Stores后渲染主视图 var app = cardioCatalogQT.Application.instance; app.loadRequiredStores(function() { // 渲染主视图并关闭登录窗口 Ext.widget('main-view'); this.getView().destroy(); }, this); } else { // 认证失败提示 Ext.Msg.alert('错误', '用户名或密码错误'); } } });
关键说明
- 避免预加载:移除Application的
stores数组,同时确保requires中没有cardioCatalogQT.*这类会自动加载所有命名空间类的配置,防止Stores在认证前被加载。 - 动态加载时机:仅在登录成功(或页面刷新时已登录)时加载Stores,此时Cookie已存在,Rest Proxy请求不会返回401。
- 复用逻辑:将加载Stores的逻辑封装到Application的
loadRequiredStores方法中,方便在登录成功和页面刷新时复用。 - Store注册:使用
addStores方法将Stores注册到Application,确保它们被StoreManager管理,组件可以通过storeId正常获取。
内容的提问来源于stack exchange,提问作者horcle_buzz
相关产品推荐
相关产品推荐

