外部JSON和外部模板——不能同时工作

External JSON and External Template - Can't get both to work

本文关键字:外部 工作 不能 JSON      更新时间:2023-09-26

我刚刚开始了解Handlebars.JS,我可以看到它是一个非常强大的工具。

我希望能够使用外部加载的模板和外部加载的JSON来保持我的代码干净,并减少跨页面的重复。

在那一刻,我只能得到一个或另一个工作,我可以加载一个外部模板与本地JSON数据,或加载一个外部JSON文件与本地模板。但是,我想两者都做!

我在handlebars文档中看不到任何涉及外部JSON或外部模板的内容。

这是我到目前为止最接近的…

我的javascript…

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Please work!</title>
    <script src="//code.jquery.com/jquery-2.0.3.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.1.2/handlebars.min.js"></script>
  </head>
  <body>

    <div id="anchor">My stuff should appear here</div>
    <script>
    var jsonData;
    function user_tracker(){ 
        $.getJSON("data/JSON_test.php", function(data) {
            jsonData = JSON.stringify(data); 
        });

        $.ajax({
            url: 'data/templates/test.php', 
            cache: true,
            success: function(data) {
                source    = data;
                template  = Handlebars.compile(source);
                $('#anchor').html(template(jsonData));
            }               
        }); 

    }

    $(document).ready(function($) {
        user_tracker();
    });

    </script>
  </body>
</html>

这是我的JSON文件…

{ "people":
    [
        {
            "family": "Lopez",
            "name": "Hugo",
            "title": "leader",
            "place": "Paris (France)",
            "introduction": "WP:Map workshop's Dino, GIS, Gdal & D3js lightener",
            "photo": "WikiAtlas_Lopez_Hugo_Yug.png",
            "twitter": "http://www.twitter.com/Hugo_lz"
        },        
        {
            "family": "Ganesh",
            "name": "Arun",
            "title": "co-leader",
            "place": "Dharamsala (India)",
            "introduction": "GIS, D3js enthusiast, interactions designers & wikidata tinker",
            "photo": "WikiAtlas_Ganesh_Arun_Planemad.jpg",
            "twitter": "http://www.twitter.com/planemad"
        },
        {
            "family": "Lopez",
            "name": "Edouard",
            "title": "Hero",
            "place": "Bordeaux (France)",
            "introduction": "Backend admin & Frontend professional webdev, scripts & stack consulting",
            "photo": "WikiAtlas_Lopez_Edouard_Lyhana8.png",
            "twitter": "http://wwww.twitter.com/edouard_lopez"
        }
    ]
}

这是我的模板文件....

<div>
Hey! I've loaded!
{{#people}}
            <div><img src="{{photo}}"><b><a href="{{twitter}}">{{family}} {{name}}</a></b> — {{title}}, {{place}} : {{introduction}}.</div>
{{/people}}
</div>

模板加载得很好,但JSON似乎没有。我在控制台没有得到任何错误。

我添加了JSON。stringify,因为我之前得到一个错误,Handlebars不喜欢传递给它的对象

我找不到go-to - duplicate问题,但这是JS中非常常见的问题,与异步执行的本质有关。

基本上,想象你需要做午餐;你决定让你的两个孩子帮忙。所以你让乔伊跑去商店买一些土豆(因为你家里没有土豆了),你让小珍从抽屉里拿刀给你(因为她当然不会割伤自己,她已经四岁了!)你决定你会开始砍,只要珍做她的差事;但既然乔伊还没回来,你得非常非常快地切完。然后,你的妻子抱怨说土豆汤里没有真正的土豆。乔伊终于回家了,因为他错过了一顿乏味的晚餐。如果你等着两个孩子,这一切都可以避免。

你的jsonData是你的土豆,你不等待的差事。你的模板是Jen的刀,你要立即完成模板编译的任务。

有两个半的解。

  • 不太好,但很简单:只有当Joey回来时才派Jen去取刀(反之亦然):

    $.getJSON("data/JSON_test.php", function(jsonData) {
        $.ajax({
          url: 'data/templates/test.php', 
          cache: true,
          success: function(source) {
              var template  = Handlebars.compile(source);
              $('#anchor').html(template(jsonData));
          }               
        });
    });
    
  • 真正的事情:在你开始做饭之前数一下你所有的孩子都在:

    var ajaxDone = 0;
    var jsonData, template;
    function runTemplate() {
      $('#anchor').html(template(jsonData));
    }
    $.getJSON("data/JSON_test.php", function(data) {
        jsonData = data; 
        if (++ajaxDone == 2) runTemplate();
    });
    $.ajax({
        url: 'data/templates/test.php', 
        cache: true,
        success: function(data) {
            var source    = data;
            template  = Handlebars.compile(source);
            if (++ajaxDone == 2) runTemplate();
        }               
    }); 
    
  • 使用承诺,它会为你做计数。

    $.when(
      $.getJSON("data/JSON_test.php"),
      $.ajax({
          url: 'data/templates/test.php', 
          cache: true,
      })
    ).then(function(responseJSON, responseTemplate) {
      // ...
    });
    

    (我不知道我的头顶上responseJSONresponseTemplate格式最终是什么,可能像[data, statusText, jqXHR]…所以,console.log他们,你自己看看土豆在哪里,刀在哪里。

编辑:我是盲目地复制粘贴,但是,是的,你不能在这里JSON.stringify

由于AJAX请求的异步特性,您最终可能会尝试在获得数据之前使用数据。解决方案是像这样使用$.Deferred:

  <script>
var jsonData;
function user_tracker(){ 
    var jsonData = getJSONData();
    var ajaxData = getAJAXData();

    $.when(ajaxData, jsonData).done(html, json){
        var template  = Handlebars.compile(html);
        $('#anchor').html(template(json);
   }


}
 function getJSONData(){
     var defObj = $.Deferred();
     $.getJSON("data/JSON_test.php", function(data) {
       defObj.resolve(JSON.parse(data)); //parse if response in JSON 
    });
    return defObj.promise();
 }
function getAJAXData(){
  var defObj = $.Deferred();
  $.ajax({
        url: 'data/templates/test.php', 
        cache: true,
        success: function(data) {
            //source    = data;
            //template  = Handlebars.compile(source);
            //$('#anchor').html(template(jsonData));
            defObj.resolve(data);
        }               
    }); 
  return defObj.promise();
}

$(document).ready(function($) {
    user_tracker();
});

</script>

查看上面的整个脚本片段