0

ロードしたテンプレートからの応答を保証するために ajax リクエストを取得しようとして立ち往生しています。

基本的に、コードを実行して遅延オブジェクトを返すと、テンプレート オブジェクトを取得する前に $.then() が呼び出されます。これは、最初の実行時にのみ発生します。

私はこれで髪を引き裂いています!

私のajax呼び出し:

var ajax = {
    getTemplate: (function (id) {
    /// <summary>
    ///     This method when used with $.Deferred fetches a html string 
    ////    containing the template appliciable 
    ///     to the the supplied id.
    ///     The ajax request object is cached upon the first request and is
    ///     returned by the cache 
    ///     upon each subsequent request.
    /// </summary>
    /// <param name="id" type="String">
    ///     The id that matches the filename to request the template object
    ///     from.
    /// </param>
    /// <returns type="jqXHR">
    ///      A superset of the XMLHTTPRequest object that impliments the
    ///      promise interface.
    /// </param>

    var cache = {}; // private cache

    // Gets assigned to getTemplate.
    return function (id) {

    var url = "/templates/" + id + ".tpl";
    return cache[id]|| $.ajax({
           url: url,
           dataType: "html",
           success: function (data) {

               //ajax.getTemplate(id, data);
               cache[id] = data;
           },
           error: function (XMLHttpRequest, textStatus, errorThrown) {
               log("template request " + id, 
                   XMLHttpRequest, 
                   textStatus, 
                   errorThrown);
           }
           });
        };
    } ())
};

私はこのように私のメソッドでこれを呼び出しています:

$.when(ajax.getTemplate("tooltip-attributes")()).then(function (template) {

    if (template) {
       // Do my template stuff here.
    }

 });
4

4 に答える 4

0

Deferred を正しく作成していないようです。

トップ関数をに変更してみてください

// Gets assigned to getTemplate.
return $.Deferred(function (id) {
于 2011-06-13T10:46:50.643 に答える
0

おそらくあなたを混乱させているのは、アウターidとインナーを持っていることidです...どちらも割り当てられません。

外部idは実際には消える可能性があります - 自己実行者の呼び出しで ID を渡した場合にのみ割り当てられます。

ここで、実際の修正は、内部関数 (によって返される関数ajax.getTemplate()) を適切に呼び出すことです。

$.when(ajax.getTemplate()("tooltip-attributes")).then(...);

「tooltip-attributes」が2 番目の括弧のセットに表示されることに注意してください。しかし、このように呼ばないのには十分な理由があります。つまり、すべてのajax.getTemplate()呼び出しには、1 つの共通キャッシュではなく、独自の独立したキャッシュがあるということです。次のようにする方が理にかなっています。

var templateGetter = ajax.getTemplate();//Assign the returned function to make it reusable
...
$.when(templateGetter("tooltip-attributes")).then(...);

個人的には、全体の構造がややこしいので、次のように Crockford スタイルのモジュール パターンを使用すると思います。

var AJAX = {
    var cache = {}; // private cache of jqXHR objects (promises)
    var getTemplate = function (id) {
        var url = "/templates/" + id + ".tpl";
        if(!cache[id]) {
            cache[id] = $.ajax({
                url: url,
                dataType: 'html',
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    log("template request " + id, XMLHttpRequest, textStatus, errorThrown);
                }
            });
        }
        return cache[id];
    };
    return {
        getTemplate: getTemplate
    }
};

今、AJAX.getTemplate()約束を返すことが保証されています。

AJAX.getTemplate("tooltip-attributes").then(function (template) {
    if (template) {
        // Do my template stuff here.
    }
});
于 2015-01-06T13:56:33.943 に答える
0

このチュートリアル、特に「Deferreds」セクションを参照してください。jQuery.pipe()関数に関するこのドキュメントも興味深いものです。

$.when() 内で呼び出されるすべての関数は、 $.when() が各関数の完了を待機するために、その promise() 関数を呼び出す必要があるということです。どうやらキャッシュからオブジェクトを返すことは、遅延を解決しません!

既に説明した BonyT のような $.Deferred オブジェクトを関数が常に返すようにし、promise() 関数を呼び出させることから始めます。

getTemplate: (function(id) {
    return $.Deferred(function (id) {...}
    .promise();
})()

内部リターンは、すでに存在するキャッシュされたオブジェクトまたは $.ajax xmlhttp リクエストのいずれかを提供します。後者は常に .done() コールバック ハンドラ関数で .resolve() 関数を呼び出す Deferred オブジェクトを返しますが、キャッシュ バージョンはそうではありません! そのため、ローカル キャッシュ オブジェクトからデータを抽出する場合は、手動で $.Deferred.resolve() または $.Deferred.reject() を呼び出す必要があります。

getTemplate: (function(id) {
    if (cache.hasOwnProperty(id)) {
        var dfd = $.Deferred();
        var filtered = dfd.pipe(function(value) {
            return cache[value];
        });
        return dfd.resolve(id);
    } else {
        $.ajax({
            url: url,
            dataType: "html"
        })
        .done(function(result) {
            /*fires when resolved*/
            return result;
        })
        .fail(/*fires only when rejected*/)
        .always(/*fires when both rejected or resolved*/);
    }
})()

ちなみに、.success() と .error() は、jQuery 1.8 の「非推奨通知」で非推奨になるため、これ以上使用しないでください。代わりに .done()、.fail()、および .always() を使用してください。

于 2011-09-30T10:22:17.200 に答える