6

私は、長時間実行されるロード操作を実行するのに最適な場所がどこで Durandal を使用しているかを調べようとしています。

私が知る限り、データをロードするための一般的な推奨事項は、ViewModel のactivateメソッドにあります。これは、私が通常行っていることです。

viewModel.activate = function () {
    var loadPromise = myService.loadData();

    return $.when(loadPromise).then(function (loadedData) {
        viewModel.data(data);
    });
};

ここで約束を返さない場合、通常はバインディングに問題があることを知っています-この質問と回答が示すように.

ただし、メソッドで実行時間の長いロード操作を実行するとactivate、ロード操作が完了するまでアプリが「フリーズ」します。たとえば、私の負荷が次のようになったらどうなるでしょうか?

viewModel.activate = function () {
    // All loads return a promise
    var firstLoad = myService.loadFirstData();
    var secondLoad = myService.loadSecondData();
    var thirdLoad = myService.loadThirdDataWhichTakesAges();

    return $.when(firstLoad, secondLoad, thirdLoad).then(function (one, two, three) {
        viewModel.one(one);
        viewModel.two(two);
        viewModel.three(three);
    });
};

このシナリオでは、読み込まれているページを反映するように URL が更新されますが、ページ コンテンツにはまだ前のページが表示されます (これが「フリーズ」の意味です)。

理想的には、URL が新しいページに変更され、ページ コンテンツにも新しいページが表示されるとよいでしょう (そのページのデータがまだ返されていなくても)。次に、各読み込み操作が返されるたびに、データがビュー モデルにバインドされるときに、ページの関連部分を更新する必要があります。

デュランダル内でこれを達成するための推奨される方法はありますか?

私の現在の解決策は、メソッドでロードを開始してから、activateメソッドにデータを入力するviewAttachedことです。

var loadPromise;

viewModel.activate = function () {
    // All loads return a promise
    var firstLoad = myService.loadFirstData();
    var secondLoad = myService.loadSecondData();
    var thirdLoad = myService.loadThirdDataWhichTakesAges();

    loadPromise = $.when(firstLoad, secondLoad, thirdLoad);

    // Don't return the promise - let activation proceed.
};

viewModel.viewAttached = function () {
    $.when(loadPromise).then(function (one, two, three) {
        viewModel.one(one);
        viewModel.two(two);
        viewModel.three(three);
    });
};

うまくいくようですが、依存するviewAttachedのは良い解決策ではないとどこかで読んだことを覚えています。また、アクティブ化を許可しているため、競合状態が発生する可能性があるかどうかもわかりません。

他の推奨事項はありますか?

4

3 に答える 3

0

参考のため; 私は Durandal Google Group に同様の質問を投稿し (この方法で activate と viewAttached を使用することは問題ないかどうかを効果的に尋ねています)、Rob Eisenberg から次のような返信がありました。

それはおそらくうまくいくでしょう。問題は、プロパティが更新され、要素が現在ドキュメントにない場合、Knockout が要素のデータバインディングを破棄することです。これは、非同期コードのタイミングによって発生する可能性があります。1.x でのコンポジションの動作方法により、activate 関数から promise を返さなかった場合に問題が発生します。viewAttached の方が適切に機能するはずですが、コンポジションの性質によっては、ビューがその親に関連付けられていても、ドキュメントには含まれていない場合があります。それは構成の深さに依存します。したがって、これが深く構成されたモジュールにある場合、これでも問題が発生する可能性があります。残念ながら、Durandal 1.x ではノックアウト動作のため、クリーンな方法はありません。デュランダル2で。x この問題が存在しないようにコンポジションを作り直し、プロミスを返す必要がなくなりました (まだ実行できますが)。デュランダル 2.0 は約 2 週間でリリースされます。

于 2013-08-01T05:17:51.903 に答える