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テスト

3つのことに注意してください。

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"  
    },  ...

オブジェクトを参照するための「リスト」を作成しました。次に、プロパティ「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 に答える