0

ページの読み込み時にアイテム ID のリストがあります。

var itemIds = [1, 5, 10, 11];

ID はリストにレンダリングされ、ユーザーに表示されます。アイテムの詳細情報をロードする関数があり、Promise/A を返します。

function loadInfo(id) { ... }

すべてのアイテムの情報の読み込みは、ページの読み込み時に開始されます。

val infos = {};
$.each(itemIds, function(i, id) { infos[id] = loadInfo(id); }

今問題自体。

ユーザーがアイテム ID をクリックすると:

  • アイテム情報がロードされている場合、情報を表示する必要があります
  • アイテム情報がまだロードされていない場合は、ロード時に表示する必要があります

簡単に見えます:

$('li').click(function() {
    var id = $(this).data('item-id');
    infos[id].then(function(info) { $('#info').text(info); });
});

しかし、現在のアイテムがロードされる前にユーザーが別のアイテムを気に入った場合は、現在のアイテムの約束のハンドラーをキャンセルし、新しいアイテムのスケジュールを設定する必要があります。

適切に行う方法は?

私はいくつかの実用的な解決策( currentItemId 変数を維持し、それを約束ハンドラでチェックするなど)を持っていますが、それらは醜いです。代わりに、リアクティブ プログラミング ライブラリを検討する必要がありますか?

4

1 に答える 1

0

クリオマント、

これをコーディングする方法はいくつかあると思います。これが1つです:

var INFOS = (function(){
    var infoCache = {},
        promises = {},
        fetching = null;

    var load = function(id) {
        if(!promises[id]) {
            promises[id] = $ajax({
                //ajax options here
            }).done(function(info){
                infoCache[id] = info;
                delete promises[id];
            });
        }
        return promises[id];
    }

    var display = function(id, $container) {
        if(fetching) {
            //cancel display (but not loading) of anything latent.
            fetching.reject();
        }
        if(infoCache[id]) {
            //info is already cached, so simply display it.
            $container.text(infoCache[id]);
        }
        else {
            fetching = $.Deferred().done(function() {
                $container.text(infoCache[id]);
            });
            load(id).done(fetching.resolve);
        }
    }
    return {
        load: load,
        display: display
    };
})();

ご覧のとおり、複雑さはすべて名前空間INFOSにまとめられており、2 つのメソッドが公開されています。loaddisplay

メソッドを呼び出す方法は次のとおりです。

$(function() {
    itemIds = ["p7", "p8", "p9"];

    //preload
    $.each(itemIds, function(i, id) { INFOS.load(id); });

    //load into cache on first click, then display from cache.
    $('li').on('click', function() {
        var id = $(this).data('item-id');
        INFOS.display(id, $('#info'));
    });
});

デモ(シミュレートされた ajax を使用)

ここでのトリックは次のとおりです。

  • IDでインデックス化された情報をキャッシュする
  • id でインデックス付けされたアクティブな jqXHR promise をキャッシュする
  • 以前にロードされた場合にキャッシュから情報を表示するには ...
  • ...それ以外の場合は、情報が要求されるたびに、情報の表示に関連付けられた Deferred を作成します。これは、対応する jqXHR とは無関係に解決/拒否できます。
于 2013-01-23T02:57:34.597 に答える