我刚刚开始了解Handlebars.JS,我可以看到它是一个非常强大的工具。
我希望能够使用外部加载的模板和外部加载的JSON来保持我的代码清洁,并减少页面间的重复。
当我只能使用其中一个工作时,我可以使用本地JSON数据加载外部模板,或者使用本地模板加载外部JSON文件。但是,我想两个都做!
我在车把文档上看不到任何内容,包括外部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不喜欢传递给它的对象。
答案 0 :(得分:3)
我找不到复制问题,但这是JS中一个非常常见的问题,并且与异步执行的性质有关。
基本上,想象你需要做午饭;而你决定让你的两个孩子帮忙。所以你告诉乔伊跑到商店去买一些土豆(因为你家里没有土豆),你告诉小仁从抽屉里拿出刀子(因为她当然不会剪掉自己,她已经四岁了!)你决定一旦Jen做她的差事你就会开始砍;但由于乔伊还没有回来,你很快就完成了砍伐。然后,你的妻子抱怨土豆汤中没有真正的土豆。乔伊终于回家了,错过了(非常平淡的)晚餐。如果你等两个孩子,所有这一切都可以避免。
你的jsonData
是你的土豆,你不等的差事。你的模板是Jen的刀,这是你在模板编译后立即遵循的差事。
有两个半解决方案。
不是很好,但很简单:只有当乔伊回来时才送刀给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();
}
});
使用promises,它会为你计算。
$.when(
$.getJSON("data/JSON_test.php"),
$.ajax({
url: 'data/templates/test.php',
cache: true,
})
).then(function(responseJSON, responseTemplate) {
// ...
});
(我不知道最终responseJSON
和responseTemplate
格式是什么,可能类似于[data, statusText, jqXHR]
......所以,console.log
他们,亲眼看看哪里的土豆和哪里的刀。)
JSON.stringify
在这里。勒米很快就剥掉了。
答案 1 :(得分:0)
由于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>
请参阅上面的整个脚本代码段