2

アコーディオンプラグインで口ひげjsを使用しています。私の考えは、外部のjsonファイルとともに外部のテンプレートファイルを使用し、テンプレート化されたファイルを(プラグインを使用して)アコーディオンウィジェットにプルすることです。私のアコーディオンが機能していないことを除いて、すべて正常に機能します。コードをチェックするためにアラートが使用されている場合にのみ機能します。Html は基本的な Jquery ライブラリ呼び出しであり、コンテンツを保持する div です。どんな助けでも大歓迎です。

$(document).ready(function () {
    $('head').append("<script id='templateHolder' type='text/template'></script");

    $('#templateHolder').load('templates/template.html', function () {
        var scripts = ['js/liteaccordion.jquery.js', 'js/mustache.js']; //add as many script as required here
        for (var i = 0; i < scripts.length; i++) {
            $.getScript(scripts[i], function () {
                $.getJSON('json/data.json', function (data) {
                    var template = $('#templateHolder').html();
                    var info = Mustache.to_html(template, data);
                    $('.jsoncontent').html(info);
                });
                //alert('done'); 
                //not working without alert?
                $('.jsoncontent').liteAccordion();
            });
        }
    });
});
4

3 に答える 3

3

問題は、関数$.getJSONが非同期で実行されるため、この命令の$('.jsoncontent').liteAccordion();前に命令が実行される$('.jsoncontent').html(info);ことalertです。実行を停止しているため、命令を実行すると、命令が実行される前$('.jsoncontent').html(info);に終了する時間があるため、機能する可能性があります$('.jsoncontent').liteAccordion();

考えられる修正は、最善の修正ではないかもしれませんが、最も簡単な方法は、$.getJSON の実行を同期的に実行することです。これにより、次のコード ブロックが置き換えられます。

                $.getJSON('json/data.json', function (data) {
                    var template = $('#templateHolder').html();
                    var info = Mustache.to_html(template, data);
                    $('.jsoncontent').html(info);
                });

このため:

$.ajax({
    url: 'json/data.json',
    dataType: 'json',
    success: function (data) {
                    var template = $('#templateHolder').html();
                    var info = Mustache.to_html(template, data);
                    $('.jsoncontent').html(info);
                },
    data: {},
    async: false
});

編集

コードに別の重要な問題があることに気付きました.「for」の実行で、最初にJqueryライブラリをロードし、次にMustacheライブラリをロードしているようです. しかし、JQueryライブラリをロードした後、「Mustache」ライブラリをロードする前に、関数「Mustache」を使用しようとしています...それは問題です。

これを試して:

$(document).ready(function () {
    $('head').append("<script id='templateHolder' type='text/template'></script");

    $('#templateHolder').load('templates/template.html', function () {
        var scripts = ['js/liteaccordion.jquery.js', 'js/mustache.js']; //add as many script as required here
        var scriptsLoaded =0;
        for (var i = 0; i < scripts.length; i++) {
            $.getScript(scripts[i], function () {
                scriptsLoaded++;
                if(scriptsLoaded==scripts.length){
                    $.getJSON('json/data.json', function (data) {
                        var template = $('#templateHolder').html();
                        var info = Mustache.to_html(template, data);
                        $('.jsoncontent').html(info);
                        $('.jsoncontent').liteAccordion();
                    });
                }    
            });
        }
    });
});
于 2013-01-02T14:51:25.970 に答える
1

Josep は正しいです。alert() を使用しているときに機能する場合は、それが実行をブロックしているためです。これにより、ajax 呼び出しが機能し、コールバックが実行される時間が与えられます。

$.liteAccordion()ただし、コードをそれほどリファクタリングするのではなく、呼び出しをコールバックに移動するだけで済みます。例えば:

$(document).ready(function () {
    $('head').append("<script id='templateHolder' type='text/template'></script");

    $('#templateHolder').load('templates/template.html', function () {
        var scripts = ['js/liteaccordion.jquery.js', 'js/mustache.js']; //add as many script as required here
        for (var i = 0; i < scripts.length; i++) {
            $.getScript(scripts[i], function () {
                $.getJSON('json/data.json', function (data) {
                    var template = $('#templateHolder').html();
                    var info = Mustache.to_html(template, data);
                    $('.jsoncontent').html(info);
                    $('.jsoncontent').liteAccordion(); //move here
                }); //eof .getJSON
            }); //eof .getScript()
        } //eof for()
    }); //eof load()
}); //eof ready()

$.getScript()ただし、ループ内のコードfor()は実際にはそのように実行する必要がないため、使用の選択については少し興味があります。スクリプトごとに 1 回ずつ JSON を取得しても意味がありません。すべてのスクリプトを取得し、JSON を一度取得することをお勧めします。たとえば、..

$(document).ready(function () {
    $('head').append("<script id='templateHolder' type='text/template'></script");

    $('#templateHolder').load('templates/template.html', function () {
        var scripts = ['js/liteaccordion.jquery.js', 'js/mustache.js']; //add as many script as required here
        for (var i = 0; i < scripts.length; i++) {
            $.getScript(scripts[i], function () {
                //just get the script; this callback doesn't need to do anything really
            }); //eof .getScript()
        } //eof for()

       /* we're out of the for() loop now, so this will only make the call
          once; however - all our scripts are loaded so it will work */
       $.getJSON('json/data.json', function (data) {
            var template = $('#templateHolder').html();
            var info = Mustache.to_html(template, data);
            $('.jsoncontent').html(info);
            $('.jsoncontent').liteAccordion(); //move here
        }); //eof .getJSON

    }); //eof load()
}); //eof ready()

このソリューションでは、$.liteAcordion()呼び出しをコールバックに配置するため、Mustache.js が呼び出された後に実行されます。

コールバック関数などを最大限に活用しないと頭痛の種になる可能性があるため、AJAX は時々非同期であることを覚えておく価値があります。

ただし、@Josep が以下のコメントで指摘しているように、まだ実行$.getScript()が完了していないというリスクがあります。これは、配列に含めるスクリプトが増えると問題になります。

それを念頭に置いて、わずかなリファクタリングを行い、ループから呼び出す$.getJSON()ことをお勧めします。for()ただし、それが確実に最後の反復であることを確認してください。(編集: Jesop は実際には同じ解決策を持っていたようです。私たちのほとんどがポイントを獲得するためにここにいることは知っていますが、回答を受け入れる場合は、彼を受け入れてください。彼が最初にそこにたどり着きました;) )

$(document).ready(function () {
    $('head').append("<script id='templateHolder' type='text/template'></script");

    $('#templateHolder').load('templates/template.html', function () {
        var scripts = ['js/liteaccordion.jquery.js', 'js/mustache.js']; //add as many script as required here
        for (var i = 0; i < scripts.length; i++) {
            $.getScript(scripts[i], function () {
                if( i == (scripts.length -1) )
                  $.getJSON('json/data.json', function (data) {
                      var template = $('#templateHolder').html();
                      var info = Mustache.to_html(template, data);
                      $('.jsoncontent').html(info);
                      $('.jsoncontent').liteAccordion(); //move here
                  }); //eof .getJSON

            }); //eof .getScript()
        } //eof for()
    }); //eof load()
}); //eof ready()
于 2013-01-02T15:41:06.127 に答える
0

josep が指摘したように、for ループは問題を引き起こします。口ひげの影響を受けない js をロードするのに役立つため、今のところスクリプト配列を保持しています。JSON コールバックの get スクリプトが機能します。

$(document).ready(function(){

        $('head').append("<script id='templateHolder' type='text/template'></script");

        $('#templateHolder').load('templates/template.html',function(){
            var scripts = ['js/mustache.js'];
            //problem here for any scripts directly affected by moustache templating.
                 for(var i = 0; i < scripts.length; i++){
                             $.getScript(scripts[i], function() {  
                                $.getJSON('json/data.json', function(data) {
                                            var template = $('#templateHolder').html();
                                            var info = Mustache.to_html(template, data);
                                            $('.jsoncontent').html(info);
                                            $.getScript('js/liteaccordion.jquery.js', function() {
                                            $('.jsoncontent').liteAccordion();
                                     });
                                 });
                            });
                 }
        });
    });
于 2013-01-02T16:29:21.190 に答える