0

[編集] ここにも 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);
            }
        }

おそらく、これをモンキーパッチする方法はありますか?できればデュランダルのコア部分の編集は避けたいです。

4

1 に答える 1

1

複数のシェルを実装する必要はありません。私たちも最初はこれを見ていました。1 つのシェルを持つことができ、すぐにその中に内部シェルを動的に構成できます。内側のシェルは、動的な構成で交換できます。これにより、高レベルのルーティングが維持されます. つまり、すべてのビューが子ルートになる必要はありません。

つまり、次の場合、 1 レベルではなく2 レベル下に配置されます。

data-bind="router: { model: router.activeItem, cacheViews:false, compositionComplete: router.compositionComplete, attached: router.attached }">

これは内部シェルに移動されます:

<div data-bind="compose: {model: currentShell()}"></div>

wherecurrentShell()は、現在のシェル (「スーパー シェル」の viewModel 内) を保持するオブザーバブルです。

于 2014-06-16T14:40:47.667 に答える