[编辑]还有Google网上论坛帖子over here。在我了解更多内容时,我会尽量保持更新。
根据Durandal Documentation页面,Root View Model仅实现有限的Activator功能。具体而言,它声明:
...
4)当您调用app.setRoot时,在您的根模块上使用(有限的)激活器。
注意:案例4略有不同,因为它只强制执行canActivate并激活回调;不是停用生命周期。要启用它,您必须自己使用完整的激活器(例1-3)。
这意味着与所有嵌套页面ViewModel不同,root用户没有机会处理他们的垃圾对象并进行清理。
什么是友好的解雇方法当我调用app.setRoot()时,可以对这些对象进行取消激活和取消激活?我也许可以手动执行此操作,但我需要引用根ViewModel,这不一定在范围内。
我考虑过创建一个类型的发布/订阅系统,虽然我对此感到厌倦,因为它有可能导致更多的内存问题和清理复杂性,而不是减少它。
我考虑过要求这个项目,虽然这会带来一些沉重的开销,因为我不得不从那时起维护我的叉子。
[编辑]
示例:
让我们说我要开始我的应用程序并将shell设置为" main"外壳
app.start().then(function () {
app.setRoot('views/shells/main');
})
稍后,我希望切换到新的shell。也许是不同的布局,全屏或不同的皮肤。
app.setRoot('views/shells/accounts');
这将导致shell" accounts"检查和/或激活激活和canActivate,但它不会检查shell" main" for canDeactivate和deactivate。我有清理逻辑,我想在它们消失时运行。我怎么能做到这一点?
[编辑]
durandal代码部分处理这是一个本地函数,生活在模块&durandal / app' setRoot()finishComposition()看起来像这样
function finishComposition() {
if(settings.model) {
if (settings.model.canActivate) {
try {
var result = settings.model.canActivate();
if (result && result.then) {
result.then(function (actualResult) {
if (actualResult) {
composition.compose(hostElement, settings);
}
}).fail(function (err) {
system.error(err);
});
} else if (result) {
composition.compose(hostElement, settings);
}
} catch (er) {
system.error(er);
}
} else {
composition.compose(hostElement, settings);
}
} else {
composition.compose(hostElement, settings);
}
}
也许有一种方法来修补这个?如果可能的话,我想避免编辑Durandal的核心。
答案 0 :(得分:1)
您实际上不必实现多个shell。我们一开始也看了这个。你可以有一个shell,然后立即动态地组成一个内壳。内部shell可以与动态组合交换,这仍然可以保留您的高级路由。换句话说,没有必要让每个视图成为子路径。
换句话说,以下是两个级别,而不是一个:
data-bind="router: { model: router.activeItem, cacheViews:false, compositionComplete: router.compositionComplete, attached: router.attached }">
这将被移入内壳:
<div data-bind="compose: {model: currentShell()}"></div>
其中currentShell()
是一个包含当前shell的observable(在“super shell”的viewModel中)。