我正在与aurelia合作,并使用aurelia-store进行应用程序状态管理。从服务器加载数据时,我想更改isLoading字段true / false以在相关组件上显示掩码。因此,我已经在状态isLoading
中定义了一个属性(例如)。在加载操作中,我想先将加载状态更改为true,然后将数据检索为false。因此,根据该字段的值(isLoading),我想在组件上显示遮罩。
我想要这样的东西:
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文档中了解到的那样,一次操作不允许两次状态更改。
我该怎么办?
我有一个想法,首先要在此操作中调度另一个操作,以使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);
}
}
但是我找不到有关如何在一个动作中分派另一个动作的文档。
可能的解决方案是什么?
答案 0 :(得分:5)
我已尝试将您的问题简化为一个小样本,您可以在here上找到它。
initialState是这样的:
initialState: {
roles: [],
isLoading: false
}
如您所见,它具有一个角色数组,应将要加载的角色存储在其中,并带有一个isLoading
布尔值以有条件地显示加载指示符。
现在我们已经设置好示例,让我们深入研究细节。
首先可以从一个动作中远程加载数据,但应谨慎进行。 Aurelia商店的调度管道是一个异步队列。这意味着新操作将在最后自动排队。现在,如果当前执行的动作需要很长时间才能解决,您可能会遇到UI落后等问题,因为所有后续动作只会在以后更新。
第二,一个动作应该创建一个新状态。您实际上想要执行的操作将包含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)
);
}