Aurelia - 在路由器预渲染步骤中等待 return 的承诺
Aurelia - waiting for a promise to return in the router prerender step
TL;DR - 如何延迟 aurelia-router.js
中的 ProcessResult()
函数执行,因为我仍在等待承诺的结果在我的代码中?它导致正确的模块呈现,错误的 address/href.
示例:如果您在基础模块上,然后单击管理,管理模块将加载,但 href
仍然是 www.mycompany.com/#/base-module
而不是 www.mycompany.com/#/admin
,并且这可以在控制台看到错误:
ERROR [app-router] Error: Expected router pipeline to return a navigation result, but got [{}] instead
更长的版本:
我的路由器中有一个预呈现步骤,用于在呈现视图之前检查用户是否启用了特定模块。
在我的 PreRenderStep class 中,我有一个 运行 函数,它调用一个中介来获取用户的权限,然后检查用户点击的模块是否在他们启用的模块列表中.调用调解器涉及承诺。
问题是预呈现步骤中的 运行 承诺在 运行 方法中的承诺完成之前解决。因此,最终呈现视图(因为用户已启用)但之前的 href 仍保留在地址栏中。
路由器:
configureRouter(config, router) {
config.title = "Tramonex";
config.addPipelineStep('authorize', AuthorizeStep);
config.addPreRenderStep(PreRenderStep);
config.map([
{
route: ['', 'log-in-out'],
name: 'home',
moduleId: 'modules/authentication/log-in-out'
},
{
route: 'passwordReset',
moduleId: 'modules/authentication/password-reset',
},
{route: 'app', moduleId: 'app', auth: true},
{
route: 'base-module',
name: 'base-module',
moduleId: 'modules/base-module',
href: 'base-module',
nav: true,
auth: true
},
{
route: 'test1',
name: 'test1',
moduleId: 'modules/test1/test1',
href: 'test1',
nav: true,
auth: true,
settings: {moduleAuthRequired: true}
},
{
route: 'test2',
name: 'test2',
moduleId: 'modules/test2/test2',
href: 'test2',
nav: true,
auth: true,
settings: {moduleAuthRequired: true}
},
{
route: 'admin',
name: 'admin',
moduleId: 'modules/admin/admin',
href: 'admin',
nav: true,
auth: true,
settings: {moduleAuthRequired: true}
},
]);
this.router = router;
}
}
PreRenderStep:
@inject(Mediator, AuthenticationService)
class PreRenderStep {
constructor(mediator, authenticationService) {
this.mediator = mediator;
this.authenticationService = authenticationService;
}
run(navigationInstruction, next) {
if (navigationInstruction.getAllInstructions().some(i => i.config.settings.moduleAuthRequired)) {
this.redirect = false;
this.mediator.getPermissionsForUser()
.then(user => {
userPerms = user.modules;
var isEnabled = userPerms.includes(navigationInstruction.config.name);
if (!isEnabled) {
this.redirect = true;
}
})
.then(() => {
return this.redirect next.cancel(navigationInstruction.router.navigateToRoute('base-module')) : next();
});
}
else {
return next();
}
}
}
当用户点击一个需要验证检查的模块时,代码被命中,而当我们等待从 mediator.getPermissionsForUser() 到 return 的承诺时,这段代码在aurelia-router.js 被击中(带星号的线):
function processResult(instruction, result, instructionCount, router) {
if (!(result && 'completed' in result && 'output' in result)) {
result = result || {};
**result.output = new Error('Expected router pipeline to return a navigation result, but got [' + JSON.stringify(result) + '] instead.');**
}
var finalResult = null;
if (isNavigationCommand(result.output)) {
result.output.navigate(router);
} else {
finalResult = result;
if (!result.completed) {
if (result.output instanceof Error) {
logger.error(result.output);
}
**restorePreviousLocation(router);**
}
}
您需要 return 您在 运行 函数中创建的承诺。
return this.mediator.getPermissionsForUser()
TL;DR - 如何延迟 aurelia-router.js
中的 ProcessResult()
函数执行,因为我仍在等待承诺的结果在我的代码中?它导致正确的模块呈现,错误的 address/href.
示例:如果您在基础模块上,然后单击管理,管理模块将加载,但 href
仍然是 www.mycompany.com/#/base-module
而不是 www.mycompany.com/#/admin
,并且这可以在控制台看到错误:
ERROR [app-router] Error: Expected router pipeline to return a navigation result, but got [{}] instead
更长的版本:
我的路由器中有一个预呈现步骤,用于在呈现视图之前检查用户是否启用了特定模块。
在我的 PreRenderStep class 中,我有一个 运行 函数,它调用一个中介来获取用户的权限,然后检查用户点击的模块是否在他们启用的模块列表中.调用调解器涉及承诺。
问题是预呈现步骤中的 运行 承诺在 运行 方法中的承诺完成之前解决。因此,最终呈现视图(因为用户已启用)但之前的 href 仍保留在地址栏中。
路由器:
configureRouter(config, router) {
config.title = "Tramonex";
config.addPipelineStep('authorize', AuthorizeStep);
config.addPreRenderStep(PreRenderStep);
config.map([
{
route: ['', 'log-in-out'],
name: 'home',
moduleId: 'modules/authentication/log-in-out'
},
{
route: 'passwordReset',
moduleId: 'modules/authentication/password-reset',
},
{route: 'app', moduleId: 'app', auth: true},
{
route: 'base-module',
name: 'base-module',
moduleId: 'modules/base-module',
href: 'base-module',
nav: true,
auth: true
},
{
route: 'test1',
name: 'test1',
moduleId: 'modules/test1/test1',
href: 'test1',
nav: true,
auth: true,
settings: {moduleAuthRequired: true}
},
{
route: 'test2',
name: 'test2',
moduleId: 'modules/test2/test2',
href: 'test2',
nav: true,
auth: true,
settings: {moduleAuthRequired: true}
},
{
route: 'admin',
name: 'admin',
moduleId: 'modules/admin/admin',
href: 'admin',
nav: true,
auth: true,
settings: {moduleAuthRequired: true}
},
]);
this.router = router;
}
}
PreRenderStep:
@inject(Mediator, AuthenticationService)
class PreRenderStep {
constructor(mediator, authenticationService) {
this.mediator = mediator;
this.authenticationService = authenticationService;
}
run(navigationInstruction, next) {
if (navigationInstruction.getAllInstructions().some(i => i.config.settings.moduleAuthRequired)) {
this.redirect = false;
this.mediator.getPermissionsForUser()
.then(user => {
userPerms = user.modules;
var isEnabled = userPerms.includes(navigationInstruction.config.name);
if (!isEnabled) {
this.redirect = true;
}
})
.then(() => {
return this.redirect next.cancel(navigationInstruction.router.navigateToRoute('base-module')) : next();
});
}
else {
return next();
}
}
}
当用户点击一个需要验证检查的模块时,代码被命中,而当我们等待从 mediator.getPermissionsForUser() 到 return 的承诺时,这段代码在aurelia-router.js 被击中(带星号的线):
function processResult(instruction, result, instructionCount, router) {
if (!(result && 'completed' in result && 'output' in result)) {
result = result || {};
**result.output = new Error('Expected router pipeline to return a navigation result, but got [' + JSON.stringify(result) + '] instead.');**
}
var finalResult = null;
if (isNavigationCommand(result.output)) {
result.output.navigate(router);
} else {
finalResult = result;
if (!result.completed) {
if (result.output instanceof Error) {
logger.error(result.output);
}
**restorePreviousLocation(router);**
}
}
您需要 return 您在 运行 函数中创建的承诺。
return this.mediator.getPermissionsForUser()