【问题标题】:Mustache and Jquery Plugin IssueMustache 和 Jquery 插件问题
【发布时间】:2013-01-02 14:45:21
【问题描述】:

我正在使用带有手风琴插件的 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();
            });
        }
    });
});

【问题讨论】:

    标签: jquery ajax json templates mustache


    【解决方案1】:

    问题是函数$.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();
                        });
                    }    
                });
            }
        });
    });
    

    【讨论】:

    • 粘贴的代码现在在 .jsoncontent div 中没有得到响应。
    • 我的错,现在试试。在成功函数的末尾有一个“);”那应该是“}”,我已经修好了。
    • 在我使用 ajax 调用时仍然遇到这个无响应的问题。函数会是更好的解决方案吗?
    • 如果这个代码:"$.getJSON('json/data.json', function (data) { " 得到响应,那么我建议的代码也会得到响应。$. getJSON 只是“$.ajax”函数的简写。api.jquery.com/jQuery.getJSON
    • 好的,我现在有一个响应 - 但是结果仍然相同,没有手风琴功能。感谢您的想法,还有其他建议吗?
    【解决方案2】:

    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 在下面的 cmets 中指出的那样,您仍然面临$.getScript() 尚未完成执行的风险;对于您在数组中包含的更多脚本,这将是一个问题。

    考虑到这一点,稍微重构一下并从for() 循环中调用$.getJSON() 可能会更好;但确保它绝对是 last 迭代。 (编辑:我看到 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()
    

    【讨论】:

    • 您提出的第二个代码块的问题是,当函数“$.getJSON”被执行时,JQuery 库很可能还没有被加载......所以我认为如果他想完成这项工作,他将不得不更好地利用 $.getScript 的回调函数。
    • 很好看的何塞普。让我编辑我的帖子以实际考虑到这一点!
    • 我刚刚在我的回答中修复了它
    • 是的,伟大的思想家都喜欢。我打算使用if() 块。我会再次 +1 你的答案,但我不能。 ;)
    • 我也会再次 +1 你的答案,但我不能;)
    【解决方案3】:

    正如 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();
                                         });
                                     });
                                });
                     }
            });
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-17
      • 2012-08-16
      • 1970-01-01
      • 2013-07-24
      • 2010-11-26
      相关资源
      最近更新 更多