21

私はまだ頭を包み込もうとしてdeferredいますが、そうではないので、これを念頭に置いて、次の方法について質問があります。

私のチームと私には3つの別々の.load()メソッドがあり、それぞれが特定のテンプレートを取得して同じコンテナーに追加します。各ロードには、ご想像のとおり異なる時間がかかるため、コンテンツがロードされると、「階段状」の方法でロードされます(1、2、3)。deferredオブジェクトを利用して、すべて完了するまで待ってから、同時に追加して「階段」アクションを削除したいと思います。

$('<div>').load(baseInfoTemplate, function () {
    var baseData = {
        // build some object
    };

    $.tmpl(this, baseData).appendTo($generalContainer);
});

3つの呼び出しはすべて、上記の呼び出しと同様です。

どうすればこれを達成できますか?

4

5 に答える 5

9

この場合、次のコードを使用します。

$.when(
    $.get('templates/navbar.tmpl.html', function(data) {
        $('#navbar').html(data);
    }),
    $.get('templates/footer.tmpl.html', function(data) {
        $('#footer').html(data);
    }),
    $.Deferred(function(deferred) {
        $(deferred.resolve);
    })
).done(function() {
    $.getScript("js/tools/jquery.min.js");
});

私の考えでは、以前の実装よりも構造化されていて、かなり素敵に見えます。

于 2013-09-06T10:21:24.550 に答える
6

promise objectsを配列に格納$.when()し、それらの約束が満たされているかどうかを確認するために使用できます。これは次のようになります。

var templates = [ ];

function createPromise( baseInfoTemplate ) {
    return $.Deferred(function( promise ) {
        $('<div>').load(baseInfoTemplate, function() {
            var baseData = { /* foobar */ };

            templates.push( baseData );
            promise.resolve();
        });
    }).promise();
}

var myPromises = [ ];

myPromises.push( createPromise( 'some data' ) );
myPromises.push( createPromise( 'even moar data' ) );
myPromises.push( createPromise( 'foo bar heay' ) );

$.when.apply( null, myPromises ).done( function() {
    templates.forEach(function( template ) {
        $.tmpl(this, template).appendTo($generalContainer);
    });
});

.apply()関数呼び出しの引数として配列を受け入れるため、ここで使用しています。つまり、基本的に、すべてのpromiseオブジェクトをに渡します.when()

: http: //jsfiddle.net/Hg77A/1/


アップデート:

Alnitakが指摘したように、「成功」コールバックハンドラーがない場合、上記の例はあまり意味がありません。でデータを転送した後に「すべて完了」ハンドラーを起動するだけで十分な場合は、 from内のpromise.load()を実行する必要があります。それは意味がありますか?.resolve()success handler.load()

于 2011-06-28T13:33:52.297 に答える
5

$.load()Deferred オブジェクトで使用するように設計されていません。また、ページにすぐに何かをドロップすることも特に意図されています。

後者の問題を解決するには、コンテナー全体を DOM の外部でレンダリングし、すべてが完了したらドロップするか、3 つの結果を蓄積してから一度にすべてを配置する必要があります。

以下のプロセスでは、後者のアプローチを使用します。

  1. 代わりに使用して、によって返されるオブジェクト$.get()の配列を作成します。jqXHR$.get()

  2. それぞれからの戻りフラグメント$.get()も配列に格納します

  3. $.when.apply($, myArray).done(function() { ... })テンプレートを適用してDOMに配置するために使用します

http://jsfiddle.net/alnitak/WW3ja/を参照してください

于 2011-06-28T13:49:12.127 に答える
2

次のコードを汎用ライブラリとして使用します

var loader = {};
(function(){
  var fn = {  
    promises: [],
    templates: [],

    loadTemplate: function( name ) {
      fn.promises.push(
        $.get( `templates/${name}.tmpl.html`,
               (html) => fn.templates.push( html )
        )
      );
    },

    main: function( templates, callback ) {
      templates.forEach( (template) => fn.loadTemplate( template ));
      $.when.apply( $, fn.promises ).done( function() {
        $( '<div id="templates">' ).html( fn.templates.join() ).appendTo( 'body' );
        callback();
      });
    }
  };

  /* EXPORTS */
  loader.main = fn.main;
})();

次に、アプリケーションのメイン js ファイルの最初の関数として呼び出します。

function myMain() {
  ... // do all the things
}

$( document ).ready( function() {
  templates = [ 'thingies', 'wotsits', 'oojamaflips' ];
  loader.main( templates, () => myMain());
});
于 2014-07-22T10:35:43.673 に答える
2

これは、jQuery 要素のセットに loadThen 関数を追加する小さな jQuery プラグインの要点です。これは基本的にコールバックのない load() であり、コンテンツがロードされて選択された要素のセットに挿入された後にのみ解決される promise を返します。

これは基本的に、実際の ajax 呼び出しから promise を返すことを除いて、jQuery 独自の load() コードのコピー/貼り付けです。これにより、ajax が失敗した場合に拒否された promise を取得できます。

load() 機能に基づいているため、スペースで区切られた URL の後にセレクターを追加して、読み込まれた html のフラグメントのみを取得できます。


例 1:このサイトのホームページを id="container" の要素に読み込む

$('#container').loadThen('/').then(function () {
    // loaded and ready.
}, function () {
    // error
});

例 2:ホームページのヘッダーをこのページのヘッダーにロードする

$('h1').eq(0).loadThen('/ h1').then(function () {
    // loaded and ready.
}, function () {
    // error
});

要点内容:

(function ($) {
    var _loadThen = $.fn.loadThen;
    $.fn.loadThen = function (url, params) {
        if (typeof url !== "string" && _loadThen) {
            return _loadThen.apply(this, arguments);
        }

        if(this.length <= 0) {
            return jQuery.Deferred().resolveWith(this, ['']);
        }

        var selector, type, response,
            self = this,
            off = url.indexOf(" ");

        if (off >= 0) {
            selector = jQuery.trim(url.slice(off));
            url = url.slice(0, off);
        }

        if (params && typeof params === "object") {
            type = "POST";
        }

        return jQuery.ajax({
            url: url,
            type: type,
            dataType: "html",
            data: params
        }).then(function (responseText) {
                self.html(selector ? jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) : responseText);
            return self;
        });
    };
}(jQuery));
于 2014-04-11T14:25:32.847 に答える