1

我在使用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 对象,每个数字都是不同的。

那么我做错了什么,它使相同的数字重复?或者我应该怎么做才能修复它?我必须注意到我刚刚开始使用模板,所以我对它知之甚少。

4

1 回答 1

1

我将根据我对 mustache.js 的经验和handlebars.js 的在线文档来回答这个问题。我反思了我在几个基于移动的项目中使用 mustache.js 来诊断您的问题。我还阅读了 handlebars.js 文档,发现它的工作原理与 mustache.js 基本相同。

我认为问题在于您的模板标记中没有内置的块助手。当我遇到必须迭代我的源数据以解析数组中的 n 个对象的情况时,我使用库中的本机模板迭代器。我这样做是因为我可以传入一个大对象,而不必自己处理每个对象属性。模板引擎将使用它自己的内部方法为我做这件事。我只需要确保我的数据格式正确。在您的情况下,我会使用把手的“每个”块助手来迭代您的数据源。在此处查看站点文档:http: //handlebarsjs.com/

我创建了一个采用这种方法的演示。你可以在这里查看:

我的第一个 handlebars.js 测试

注意三点:

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>

我包括了“每个”迭代器,并给了它一个唯一的“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"  
    },  ...

我创建了“列表”来引用该对象。然后,我使用属性“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”方法中尝试我的渲染方法。

于 2012-06-18T21:14:39.937 回答