2

我正在使用带有手风琴插件的 mustache 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()实际上并不需要像那样运行;为每个脚本获取一次 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 循环会导致问题 - 我暂时保留了 scripts 数组,因为它有助于加载 mustache 不影响的 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 回答