在使用Handlebars.js编译模板时,我遇到了一个小问题。我有一个JSON文本文件,其中包含一个带有对象的大型数组:Source;我使用XMLHTTPRequest获取它,然后对其进行解析,以便在编译模板时使用它。
到目前为止,该模板的结构如下:
<div class="product-listing-wrapper">
<div class="product-listing">
<div class="left-side-content">
<div class="thumb-wrapper">
<img src="{{ThumbnailUrl}}">
</div>
<div class="google-maps-wrapper">
<div class="google-coordonates-wrapper">
<div class="google-coordonates">
<p>{{LatLon.Lat}}</p>
<p>{{LatLon.Lon}}</p>
</div>
</div>
<div class="google-maps-button">
<a class="google-maps" href="#" data-latitude="{{LatLon.Lat}}" data-longitude="{{LatLon.Lon}}">Google Maps</a>
</div>
</div>
</div>
<div class="right-side-content"></div>
</div>
下面这段代码就是我处理JS部分的方式:
$(document).ready(function() {
/*
Default Javascript Options
~a javascript object which contains all the variables that will be passed to the cluster class
*/
var default_cluster_options = {
animations : ['flash', 'bounce', 'shake', 'tada', 'swing', 'wobble', 'wiggle', 'pulse', 'flip', 'flipInX', 'flipOutX', 'flipInY', 'flipOutY', 'fadeIn', 'fadeInUp', 'fadeInDown', 'fadeInLeft', 'fadeInRight', 'fadeInUpBig', 'fadeInDownBig', 'fadeInLeftBig', 'fadeInRightBig', 'fadeOut', 'fadeOutUp', 'fadeOutDown', 'fadeOutLeft', 'fadeOutRight', 'fadeOutUpBig', 'fadeOutDownBig', 'fadeOutLeftBig', 'fadeOutRightBig', 'bounceIn', 'bounceInUp', 'bounceInDown', 'bounceInLeft', 'bounceInRight', 'bounceOut', 'bounceOutUp', 'bounceOutDown', 'bounceOutLeft', 'bounceOutRight', 'rotateIn', 'rotateInDownLeft', 'rotateInDownRight', 'rotateInUpLeft', 'rotateInUpRight', 'rotateOut', 'rotateOutDownLeft', 'rotateOutDownRight', 'rotateOutUpLeft', 'rotateOutUpRight', 'lightSpeedIn', 'lightSpeedOut', 'hinge', 'rollIn', 'rollOut'],
json_data_url : 'data.json',
template_data_url : 'template.php',
base_maps_api_url : 'https://maps.googleapis.com/maps/api/js?sensor=false',
cluser_wrapper_id : '#content-wrapper',
maps_wrapper_class : '.google-maps',
};
/*
Cluster
~main class, handles all javascript operations
*/
var Cluster = function(environment, cluster_options) {
var self = this;
this.options = $.extend({}, default_cluster_options, cluster_options);
this.environment = environment;
this.animations = this.options.animations;
this.json_data_url = this.options.json_data_url;
this.template_data_url = this.options.template_data_url;
this.base_maps_api_url = this.options.base_maps_api_url;
this.cluser_wrapper_id = this.options.cluser_wrapper_id;
this.maps_wrapper_class = this.options.maps_wrapper_class;
this.test_environment_mode(this.environment);
this.initiate_environment();
this.test_xmlhttprequest_availability();
this.initiate_gmaps_lib_load(self.base_maps_api_url);
this.initiate_data_processing();
};
/*
Test Environment Mode
~adds a modernizr test which looks wheater the cluster class is initiated in development or not
*/
Cluster.prototype.test_environment_mode = function(environment) {
var self = this;
return Modernizr.addTest('test_environment', function() {
return (typeof environment !== 'undefined' && environment !== null && environment === "Development") ? true : false;
});
};
/*
Test XMLHTTPRequest Availability
~adds a modernizr test which looks wheater the xmlhttprequest class is available or not in the browser, exception makes IE
*/
Cluster.prototype.test_xmlhttprequest_availability = function() {
return Modernizr.addTest('test_xmlhttprequest', function() {
return (typeof window.XMLHttpRequest === 'undefined' || window.XMLHttpRequest === null) ? true : false;
});
};
/*
Initiate Environment
~depending on what the modernizr test returns it puts LESS in the development mode or not
*/
Cluster.prototype.initiate_environment = function() {
return (Modernizr.test_environment) ? (less.env = "development", less.watch()) : true;
};
Cluster.prototype.initiate_gmaps_lib_load = function(lib_url) {
return Modernizr.load(lib_url);
};
/*
Initiate XHR Request
~prototype function that creates an xmlhttprequest for processing json data from an separate json text file
*/
Cluster.prototype.initiate_xhr_request = function(url, mime_type) {
var request, data;
var self = this;
(Modernizr.test_xmlhttprequest) ? request = new ActiveXObject('Microsoft.XMLHTTP') : request = new XMLHttpRequest();
request.onreadystatechange = function() {
if(request.readyState == 4 && request.status == 200) {
data = request.responseText;
}
};
request.open("GET", url, false);
request.overrideMimeType(mime_type);
request.send();
return data;
};
Cluster.prototype.initiate_google_maps_action = function() {
var self = this;
return $(this.maps_wrapper_class).each(function(index, element) {
return $(element).on('click', function(ev) {
var html = $('<div id="map-canvas" class="map-canvas"></div>');
var latitude = $(element).attr('data-latitude');
var longitude = $(element).attr('data-longitude');
log("LAT : " + latitude);
log("LON : " + longitude);
$.lightbox(html, {
"width": 900,
"height": 250,
"onOpen" : function() {
}
});
ev.preventDefault();
});
});
};
Cluster.prototype.initiate_data_processing = function() {
var self = this;
var json_data = JSON.parse(self.initiate_xhr_request(self.json_data_url, 'application/json; charset=ISO-8859-1'));
var source_data = self.initiate_xhr_request(self.template_data_url, 'text/html');
var template = Handlebars.compile(source_data);
for(var i = 0; i < json_data.length; i++ ) {
var result = template(json_data[i]);
$(result).appendTo(self.cluser_wrapper_id);
}
self.initiate_google_maps_action();
};
/*
Cluster
~initiate the cluster class
*/
var cluster = new Cluster("Development");
});我的问题是,我不认为我没有正确地迭代JSON对象,或者我错误地使用了模板,因为如果您检查这个链接:http://rolandgroza.com/labs/valtech/;您将看到有一些数字(代表纬度和经度),但它们都是相同的,如果您只简单地看一下JSON对象,每个数字都是不同的。
那么,我做错了什么,它使相同的数字重复?或者我应该做些什么来修复它?我必须注意到,我刚刚开始使用模板,所以我对它知之甚少。
发布于 2012-06-19 05:14:40
我将根据我使用mustache.js的经验和handlebars.js的在线文档来回答这个问题。我反思了我在几个基于移动的项目中使用mustache.js来诊断您的问题。我还阅读了handlebars.js文档,发现它的工作原理与mustache.js基本相同。
我认为问题在于模板标记中没有内置的块帮助器。当我遇到必须迭代源数据以解析数组中n个对象的情况时,我会使用库中的本机模板迭代器。我这样做是因为我可以传入一个大对象,而不必自己处理每个对象属性。模板引擎将使用它自己的内部方法为我做这件事。我只需要确保我的数据格式正确。在您的例子中,我将使用handlebars的"each“块帮助器来迭代您的数据源。请参阅此处的站点文档:http://handlebarsjs.com/
我创建了一个采用这种方法的演示。您可以在此处查看:
my first handlebars.js test
注意三件事:
1.)我对你的模板标记做了调整:
<script id="entry-template" type="text/x-handlebars-template">
{{#each productListing}}
<div class="product-listing-wrapper">
<div class="product-listing">
<div class="left-side-content">
<div class="thumb-wrapper">
<img src="{{ThumbnailUrl}}" height="250" width="200" />
</div>
<div class="google-maps-wrapper">
<div class="google-coordonates-wrapper">
<div class="google-coordonates">
<p>{{LatLon.Lat}}</p>
<p>{{LatLon.Lon}}</p>
</div>
</div>
<div class="google-maps-button">
<a class="google-maps" href="#" data-latitude="{{LatLon.Lat}}" data-longitude="{{LatLon.Lon}}">Google Maps</a>
</div>
</div>
</div>
<div class="right-side-content"></div>
</div>
</div>
{{/each}}
</script>我包含了'each‘迭代器,并给它一个唯一的散列"productListing“。散列将允许我将我的数据源对象映射到这个模板迭代器。
2.)我对数据源进行了更改。数据如下所示:
var listings = { productListing: [
{
"PropertyId":"148B4337",
"Status":"T",
"Address":"Frederiksberggade 25C",
"Placename":null,
"ThumbnailUrl":"http://streaming.home.dk/sager/148B4337/foto/size3/148B4337.201.JPG",
"EnergyClassification":"",
"Price":4995000,
"Downpayment":250000,
"Brutto":34092,
"Netto":29068,
"BuiltYear":1900,
"NumberOfFloors":null,
"NumberOfRooms":5,
"Size":194,
"LotSize":0,
"Broker":{
"BrokerId":"10000",
"Name":"Andre kæder",
"Email":"support@danbolig.dk",
"Phone":"12341234"
}, ...我创建了"listings“来引用对象。然后,我使用"productListing“属性为您当前的数据结构创建了一个外部对象。"productListing“允许我将带有对象的数组映射到模板标记。
3.)然后我用这个javascript让它全部工作:
$(document).ready(function(){
var templateSource = $('#entry-template').html();
var template = Handlebars.compile(templateSource);
var context = listings;
var html = template(context);
$(html).appendTo('#content');
});您可以在您的"Cluster.prototype.initiate_data_processing“方法中尝试我的呈现方法。
https://stackoverflow.com/questions/11088734
复制相似问题