Mustache和Jquery插件问题

时间:2013-01-02 14:45:21

标签: jquery ajax json templates 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();
            });
        }
    });
});

3 个答案:

答案 0 :(得分: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();
                    });
                }    
            });
        }
    });
});

答案 1 :(得分: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()可能会很好;但要确保它绝对是 last 迭代。 (编辑:我看到Jesop实际上有一个相同的解决方案 - 我知道我们大多数人都在这里获得积分,但如果你要接受答案 - 接受他,他先到达那里;)< / em>)

$(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()

答案 2 :(得分:0)

for循环导致josep指出的问题 - 我现在保留了脚本数组,因为加载小胡子不会影响的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();
                                     });
                                 });
                            });
                 }
        });
    });