[编辑]这里还有 Google Groups 主题。随着我了解更多,我会尽量保持更新。
根据Durandal 文档,页面根视图模型仅实现有限的激活器功能。具体来说,它指出:
……
4)当你调用 app.setRoot 时,你的根模块上会使用一个(有限的)激活器。
注意:案例 4 有点不同,因为它只强制执行 canActivate 和 activate 回调;而不是停用生命周期。要启用它,您必须自己使用完整的激活器(案例 1-3)。
这意味着与所有嵌套页面 ViewModel 不同,根视图模型没有机会处理它们的垃圾对象并进行清理。
当我调用 app.setRoot() 时,在这些对象上触发 canDeactivate 和 deactivate 的友好方式是什么?我也许可以手动执行此操作,但我需要对根 ViewModel 的引用,它不一定在范围内。
我考虑过创建一个 pub/sub 系统,尽管我对此感到厌倦,因为它有可能导致更多的内存问题和清理复杂性而不是减少它。
我考虑过分叉这个项目,尽管这会带来一些沉重的开销,因为从那时起我必须维护我的分叉。
[编辑]
例子:
假设我要启动我的应用程序并将外壳设置为“主”外壳。
app.start().then(function () {
app.setRoot('views/shells/main');
})
稍后,我希望切换到新的外壳。也许是不同的布局、全屏或不同的皮肤。
app.setRoot('views/shells/accounts');
这将导致外壳“帐户”检查和/或触发激活和 canActivate,但它不会检查外壳“主”中的 canDeactivate 和停用。我有清理逻辑,希望在这些消失时运行。我怎样才能做到这一点?
[编辑]
处理的 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 的核心。