我正在使用 aurelia 进行开发,并使用 aurelia-store 进行应用程序状态管理。从服务器加载数据时,我想更改 isLoading 字段 true/false 以在相关组件上显示掩码。因此,我在状态 isLoading
中定义了一个属性(例如)。在加载操作中,我想首先将加载状态更改为 true,然后在检索数据后将其更改为 false。因此,根据此字段的值(isLoading)我想在组件上显示 mask 。
我想要这样的东西:
export async function getRoles(state) {
try {
return Object.assign({}, state, { isRolesListLoading: {busy: true} });
const getRoles = await accountManagement.getRoles();
return Object.assign({}, state, { getRoles, isRolesListLoading: {busy: false} });
} catch (error) {
console.log('error getRoles "error": ', error);
}
}
但正如我从 aurelia 文档中得出的那样,一次操作中不允许进行两次状态更改。
我应该做什么?
我有一个想法,首先在这个 Action 中调度另一个 Action ,使 isLoading 为 true,然后再完成工作。像这样的事情:
export async function getRoles(state) {
try {
desiredDispatch('goToLoadingState'); // fake code
const getRoles = await accountManagement.getRoles();
return Object.assign({}, state, { getRoles, isRolesListLoading: {busy: false} });
} catch (error) {
console.log('error getRoles "error": ', error);
}
}
但我找不到一些有关如何在一个操作中调度另一个操作的文档。
可能的解决方案是什么?
最佳答案
我试图将您的问题简化为一个小样本,您可以在 here 上找到它.
初始状态是这样的:
initialState: {
roles: [],
isLoading: false
}
正如您所看到的,它有一个角色数组,其中应存储要加载的角色和一个 isLoading
bool 值,以有条件地显示加载指示器。
现在我们已经设置了示例,让我们深入了解细节。
首先,从操作中远程加载数据是可行的,但应小心谨慎。 Aurelia Store 的调度管道是一个异步队列。这意味着新操作将自动在最后排队。现在,如果当前执行的操作需要很长时间才能解决,您可能会遇到 UI 滞后等问题,因为所有后续操作只会稍后更新。
其次,一个 Action 应该创建一个新状态。您实际上想要做的事情包括 3 个操作。
- 打开加载指示灯
- 加载数据并更新商店
- 关闭加载指示灯
就像链接的示例一样,我建议按以下方式进行:
export class App {
...
async loadRoles() {
// Activate the loader, await the action so you don't start loading before the new state is actually set
await this.store.dispatch(setLoader, true);
// Local to the function start loading the roles, so you don't block the action queue
const roles = await loadRoles();
// once the data is available update the roles
await this.store.dispatch(updateRoles, roles);
// once that is set disable the loader
await this.store.dispatch(setLoader, false);
}
}
async function loadRoles() {
return new Promise(resolve => {
setTimeout(() => {
resolve(["User role", "Admin role", "Superuser role"]);
}, 1000);
});
}
function setLoader(state, isLoading) {
return Object.assign({}, state, { isLoading });
}
function updateRoles(state, roles) {
return Object.assign({}, state, { roles });
}
现在这 3 次调度也可以减少到 2 次,因为设置数据加上禁用加载器可以一次性完成。操作的好处在于,您可以创建一个新函数,该函数通过从旧两个函数中组合一个新函数来完成此任务。
function updateRolesAndDisableLoader(state, roles) {
return Object.assign(
{},
updateRoles(state, roles),
setLoader(state, false)
);
}
关于action - Aurelia 在一次操作中两次改变状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54266405/