[編集] ここにも Google グループのスレッドがあります。詳細がわかり次第、両方を最新の状態に保つようにします。
Durandal Documentationによると、ページ Root View Model は限定された Activator 機能のみを実装しています。具体的には、次のように述べています。
....
4) app.setRoot を呼び出すと、(限定的な) アクティベーターがルート モジュールで使用されます。
注: ケース 4 は、canActivate および activate コールバックのみを強制するため、少し異なります。非アクティブ化のライフサイクルではありません。これを有効にするには、自分で完全なアクティベーターを使用する必要があります (ケース 1 ~ 3)。
つまり、ネストされたページのすべての ViewModel とは異なり、ルート ビューモデルにはジャンク オブジェクトを破棄してクリーンアップする機会がありません。
app.setRoot() を呼び出したときに、これらのオブジェクトで canDeactivate と activate の両方を起動するフレンドリーな方法は何ですか? おそらく手動でこれを行うこともできますが、必ずしもスコープ内にあるとは限らないルート ViewModel への参照が必要です。
私は一種の pub/sub システムを作成することを検討しましたが、それにはうんざりしています。それは、メモリの問題を減らしたり、クリーンアップの複雑さを軽減したりする可能性があるからです。
プロジェクトをフォークすることを検討しましたが、それ以降はフォークを維持する必要があるため、オーバーヘッドが大きくなります。
[編集]
例:
アプリケーションを起動し、シェルを「メイン」シェルに設定するとします。
app.start().then(function () {
app.setRoot('views/shells/main');
})
しばらくして、新しいシェルに切り替えたいと思います。おそらく、別のレイアウト、全画面表示、または別のスキンです。
app.setRoot('views/shells/accounts');
これにより、シェルの「アカウント」がアクティブ化および canActivate をチェックおよび/または起動しますが、シェルの「メイン」で canDeactivate および非アクティブ化をチェックしません。これらがなくなったときに実行したいクリーンアップ ロジックがあります。どうすればこれを達成できますか?
[編集]
デュランダル コードの一部は、モジュール '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);
}
}
おそらく、これをモンキーパッチする方法はありますか?できればデュランダルのコア部分の編集は避けたいです。