markdown 在使用AJAX呈现的Handlebars.js模板文件上显示平面JSON文件中的数据。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown 在使用AJAX呈现的Handlebars.js模板文件上显示平面JSON文件中的数据。相关的知识,希望对你有一定的参考价值。

{"objects": [{"Source": "National Employment Law Project", "DataOrder": "1", "SourceLink": "http://www.nelp.org/", "Data": "12.29.2012", "Title": "The last day anyone will receive benefits from the Emergency Unemployment Compensation program unless Congress acts to renew it."}, {"Source": "Congressional Budget Office", "DataOrder": "2", "SourceLink": "", "Data": "$30,000,000,000", "Title": "Estimated cost to renew the Emergency Unemployment Compensation program through the end of 2013."}, {"Source": "National Employment Law Project", "DataOrder": "3", "SourceLink": "http://www.nelp.org/", "Data": "400,000", "Title": "Estimated number of Californians receiving benefits from the Emergency Unemployment Compensation program, which is set to expire Jan. 2."}, {"Source": "National Employment Law Project", "DataOrder": "4", "SourceLink": "http://www.nelp.org/", "Data": "2,100,000", "Title": "Estimated number of Americans receiving benefits under the Emergency Unemployment Compensation program that would lose their unemployment benefits come January if Congress doesn’t act."}, {"Source": "National Employment Law Project", "DataOrder": "5", "SourceLink": "http://www.nelp.org/", "Data": "940,000", "Title": "Estimated number of Americans whose state unemployment benefits will end in the first quarter of 2013, and would be eligible for benefits under the Emergency Unemployment Compensation program."}, {"Source": "National Employment Law Project", "DataOrder": "6", "SourceLink": "http://www.nelp.org/", "Data": "February 2012", "Title": "The date when the Emergency Unemployment Compensation program was last renewed by Congress."}, {"Source": "U.S. Department of Labor", "DataOrder": "7", "SourceLink": "http://www.ows.doleta.gov/unemploy/supp_act.asp", "Data": "June 30, 2008", "Title": "The date the Emergency Unemployment Compensation program was created."}, {"Source": "National Employment Law Project", "DataOrder": "8", "SourceLink": "http://www.nelp.org/", "Data": "10", "Title": "The number of times Congress has renewed the Emergency Unemployment Compensation program since it was first created in the summer of 2008."}, {"Source": "National Employment Law Project", "DataOrder": "9", "SourceLink": "http://www.nelp.org/", "Data": "37 percent", "Title": "Estimated percent of Californians that have been unemployed more than a year since 2008, when the Emergency Unemployment Compensation program was created to help the long-term unemployed."}, {"Source": "National Employment Law Project", "DataOrder": "10", "SourceLink": "http://www.nelp.org/", "Data": "5,000,000", "Title": "Estimated number of Americans that have been without work for six months or longer"}, {"Source": "U.S. Department of Labor", "DataOrder": "11", "SourceLink": "http://workforcesecurity.doleta.gov/unemploy/docs/potential_weeks_map.pdf", "Data": "26 weeks", "Title": "Cap on unemployment benefits by the least generous states."}, {"Source": "National Employment Law Project", "DataOrder": "12", "SourceLink": "http://www.nelp.org/", "Data": "14 to 47 weeks", "Title": "The range of maximum benefits states offer, subsidized by the Emergency Unemployment Compensation program."}, {"Source": "U.S. Department of Labor", "DataOrder": "13", "SourceLink": "http://workforcesecurity.doleta.gov/unemploy/docs/potential_weeks_map.pdf", "Data": "73 weeks", "Title": "Maximum length of benefits for new claimants in California under the Emergency Unemployment Compensation program."}, {"Source": "Center on Budget & Policy Priorities", "DataOrder": "14", "SourceLink": "http://www.cbpp.org/cms/index.cfm?fa=view&id=3164", "Data": "Nine states", "Title": "Number of states with unemployment rates above 9 percent in which workers are eligible for up to 47 weeks of additional benefits under the Emergency Unemployment Compensation program."}, {"Source": "U.S. Department of Labor", "DataOrder": "15", "SourceLink": "http://www.nelp.org/", "Data": "$40,000,000,000", "Title": "Estimated amount of money brought into the state of California by those receiving benefits from the Emergency Unemployment Compensation program since it began in July 2008."}]}
<title>flat-file > > ajax > handlebars</title>
<link rel="stylesheet" href="http://current.bootstrapcdn.com/bootstrap-v204/css/bootstrap.css" type="text/css" />
<style type="text/css">

    /*
    body background using Crayola crayon color from
    Ben Welsh gist: https://gist.github.com/4348665
    */

    body {background: #926EAE;}
    #data-container {background: #fff; width: 960px; margin: 0 auto 0 auto; padding: 15px;}
    #data-details {margin: 10px auto 0 auto;}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<body>
    <div id="data-container">
        <div id="data-details"></div>
    </div>
</body>

<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.rc.1/handlebars.min.js"></script>
<script type="text/javascript" src="data-script.js"></script>

    <!-- begin analytics -->
    <script type="text/javascript">
        var _gaq = _gaq || [];
        _gaq.push(['_setAccount', 'UA-20502211-1']);
        _gaq.push(['_trackPageview']);

        (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
        })();
    </script>
    <!-- end analytics -->
<div>

    {{debug}}
    <h2>Flat file data displayed on a handlebars.js template loaded with ajax</h2>
    {{#objects}}
        <p>{{Title}}: <strong>{{Data}}</strong><br />
        -- <a href="{{SourceLink}}" target="_blank"><em>{{Source}}</em></a></p>
    {{/objects}}

</div>
var jqueryNoConflict = jQuery;

//begin main function
jqueryNoConflict(document).ready(function(){
    retriveData();
});
//end main function

// grab data
function retriveData() {
    var dataSource = 'working-data-file.json';
    jqueryNoConflict.getJSON(dataSource, renderDataVisualsTemplate);
};

// render compiled handlebars template
function renderDataVisualsTemplate(data){
    handlebarsDebugHelper();
    renderHandlebarsTemplate('dataDetailsTemplate.handlebars', '#data-details', data);
};

// render handlebars templates via ajax
function getTemplateAjax(path, callback) {
    var source, template;
    jqueryNoConflict.ajax({
        url: path,
        success: function (data) {
            source = data;
            template = Handlebars.compile(source);
            if (callback) callback(template);
        }
    });
};

// function to compile handlebars template
function renderHandlebarsTemplate(withTemplate,inElement,withData){
    getTemplateAjax(withTemplate, function(template) {
        jqueryNoConflict(inElement).html(template(withData));
    })
};

// add handlebars debugger
function handlebarsDebugHelper(){
    Handlebars.registerHelper("debug", function(optionalValue) {
        console.log("Current Context");
        console.log("====================");
        console.log(this);
    });
};
# Handlebars.js template file rendered with AJAX

>**tl;dr**: The README on the repo below gives a bit of a walkthrough and demonstration of the script I've been using to display a flat data file on Handlebars templates rendered with AJAX, which has allowed me to learn to deploy interactive data projects fairly fast.
>
>- [Blog Post](http://www.chrislkeller.com/display-data-from-a-flat-json-file-on-a-handl)
>- [Demo Page](http://projects.chrislkeller.com/snippets/ajax-handlebars/)
>- [Repo](https://gist.github.com/3230081)
----

## Overview

[Handlebars.js](http://handlebarsjs.com/) is a templating library -- much like mustache.js -- that "provides the power necessary to let you build semantic templates" based on data that is formatted as -- get this -- javascript objects. Using an example from the handlebar.js website, the library allows you to do things like this...

	<div class="entry">
		<h1>{{title}}</h1>
		<div class="body">
			{{body}}
		</div>
	</div>

… where {{title}} and {{body}} represents information stored in an object like this:

	var context = {title: "My New Post", body: "This is my first post!"}

There are some really good resources out there for those who want to start using the Handlebars JavaScript template library. Here are some links:

- [Handlebars site](http://handlebarsjs.com/)
- [Handlebars GitHubRepo](https://github.com/wycats/handlebars.js/)
- [NetTuts Handlebars Walkthrough](http://net.tutsplus.com/tutorials/javascript-ajax/introduction-to-handlebars/)
- Three-part series on using Handlebars: [Part one](http://blog.teamtreehouse.com/getting-started-with-handlebars-js); [Part two](http://blog.teamtreehouse.com/code/handlebars-js-part-2-partials-and-helpers/); [Part three](http://blog.teamtreehouse.com/handlebars-js-part-3-tips-and-tricks)

I'd like to demonstrate a bit of the script I've been using to display a flat data file on Handlebars templates render with AJAX, and give a couple practical applications for using Handlebars in a newsroom environment in order to deploy interactive projects fairly fast.

## Walkthrough

Coming across Handlebars.js after learning the basics of django templating, I really wanted a way to mimic some of that functionality and store Handlebars templates in [reusable, decoupled files that could be shared across projects](https://github.com/wycats/handlebars.js/issues/82).

Thankfully this function based on [code from here](http://berzniz.com/post/24743062344/handling-handlebars-js-like-a-pro) helps me to do exactly that.

	// render handlebars templates via ajax
	function getTemplateAjax(path, callback) {
	    var source, template;
	    jqueryNoConflict.ajax({
	        url: path,
	        success: function (data) {
	            source = data;
	            template = Handlebars.compile(source);
	            if (callback) callback(template);
	        }
	    });
	}


I then abstract out a function to display the compiled template, passing in the name of the template, the css selector I am targeting and the data I want to display.

        // function to compile handlebars template
        function renderHandlebarsTemplate(withTemplate,inElement,withData){
            getTemplateAjax(withTemplate, function(template) {
                jqueryNoConflict(inElement).html(template(withData));
            })
        };

I can then call it like this, where dataDetailsTemplate.handlebars is the name of my template, and #data-details is the css selector I am targeting, and data is what I want to display.

        renderHandlebarsTemplate('dataDetailsTemplate.handlebars', '#data-details', data);

Let's go through the full [data-script.js file](https://gist.github.com/raw/3230081/31abdbfb3f4746f8fb761d196dcfa81cdd38184d/data-script.js), because there's a lot in there that I've kind of picked up over the last several months.

I don't really have an idea if it is "correct" to programmers out there, but I know that it works and doesn't throw me errors.

In learning to use jQuery in the context of my previous CMS -- which used several jQuery libraries -- I found it just made sense to use a no conflict variable and it's something I've just stuck with:

		var jqueryNoConflict = jQuery;

When the DOM is ready I call the *retriveData()* function which kind of starts the whole ball rolling:

		//begin main function
		jqueryNoConflict(document).ready(function(){
		    retriveData();
		});
		//end main function

*retriveData()* looks for my flat JSON file, which set to a variable. It then uses jQuery's getJSON method to pull the data and run it through a function called *renderDataVisualsTemplate()*. This is the function that will render my Handlebars template to the page with data in it.

		// grab data
		function retriveData() {
		    var dataSource = 'working-data-file.json';
		    jqueryNoConflict.getJSON(dataSource, renderDataVisualsTemplate);
		};

*renderDataVisualsTemplate()* gets an argument that represents my the data from my flat JSON file. This function runs my base handlebars template function using the name of my template (dataDetailsTemplate.handlebars), the css selector where I will inject my template (#data-details) and the data I will fill it with (data).

		// render compiled handlebars template
		function renderDataVisualsTemplate(data){
		    handlebarsDebugHelper();
		    renderHandlebarsTemplate('dataDetailsTemplate.handlebars', '#data-details', data);
		};

After that, I have my function to pull my Handlebars template from an external file and compile it. I've also included a Handlebars debugger, a "helper" function shows information about the data I am trying to work with.

The base handlebars template function looks like this, and takes three parameters: the name of the template, the css selector and the data object:

		// function to compile handlebars template
		function renderHandlebarsTemplate(withTemplate,inElement,withData){
		    getTemplateAjax(withTemplate, function(template) {
		        jqueryNoConflict(inElement).html(template(withData));
		    })
		};

Let's take a look at the flat JSON file I am using to hold the data that will be rendered to the page. It's structured as it is in the Handlebars walkthrough.

		{"objects": [{"Source": "National Employment Law Project", "DataOrder": "1", "SourceLink": "http://www.nelp.org/", "Data": "12.29.2012", "Title": "The last day anyone will receive benefits from the Emergency Unemployment Compensation program unless Congress acts to renew it."}, {"Source": "Congressional Budget Office", "DataOrder": "2", "SourceLink": "", "Data": "$30,000,000,000", "Title": "Estimated cost to renew the Emergency Unemployment Compensation program through the end of 2013."}]}

To render the data, the Handlebars template is structured just as it would be if it was inline on the index.html page, save for wrapping it in a script tag.

		<div>
		    {{debug}}
		    <h2>Flat file data displayed on a handlebars.js template loaded with ajax</h2>
		    {{#objects}}
		        <p>{{Title}}: <strong>{{Data}}</strong><br />
		        -- <a href="{{SourceLink}}" target="_blank"><em>{{Source}}</em></a></p>
		    {{/objects}}
		</div>

In this case, I'm asking that every instance of an object

		{{#objects}}

		{{/objects}}

be rendered to the page and structured in a certain way.

        <p>{{Title}}: <strong>{{Data}}</strong><br />
        -- <a href="{{SourceLink}}" target="_blank"><em>{{Source}}</em></a></p>

My HTML page isn't any special, other than have a div that will have all kinds of data injected into it thanks to Handlebars.

	<div id="data-details"></div>

### Practical Applications?

Your mileage might vary, but I've found several practical applications of Handlebars.js just by looking at my needs.

For instance, I came from shops that used a CMS where I could add html, css and JavaScript to a CMS "asset" which was then wrapped by the site header, rail and footer. Here at [SCPR](http://www.scpr.org/), I've been lucky enough to have mentors who wanted to and helped to create something similar.

[This project](http://projects.scpr.org/static/maps/pedestrian-safety/) is on a custom structure that lies outside of the CMS. The header and footer are each Handlebars templates, external files that I add to each new project. If I need to change a link in the footer I change it in one place and it's changed on all project pages using the template. Same goes for the header.

You could easily recreate something similar. Let's say your template structure is something like:

		<body>
		    <div id="data-header"></div>
		        <div id="data-container">
		            <div class="row-fluid">
		                <div class="span4">
		                    <div id="data-details"></div>
		                </div>
		                <div class="span8">
		                    <div id="data-visuals"></div>
		                </div>
		            </div>
		        </div>
		    <div id="data-footer"></div>
		</body>

You can probably spot some candidates for possible Handlebars templates now; data-header, data-details, data-visuals and data footer all make sense, where data-header and data-footer could be used on all projects.

Or say you want to quickly create a table to display some information. Using the data file from my earlier example, I can create a Handlebars template to do just that:

		<table class="table">
		    <tbody>
		        <tr>
		            {{#objects}}
		                <td>{{Title}}</td>
		                <td>{{Data}}</td>
		                <td>{{Source}}</td>
		            {{/objects}}
		        </tr>
		    </tbody>
		</table>

## Wrap up

As an intermediate beginner to the world of web development, and entering my fifth year of being an "online guy" in a newsroom, I've found Handlebars to be a lot of fun. To increase that fun, there are all kinds of add ons and helper functions that you can use. [swag.js](http://elving.github.com/swag/) might be the most fun thus far.

See while Handlebars tried to keep logic out of the templates -- and I respect that -- there some things I'd like to be able to do, and swag.js allows for some of that. For instance, if in my table example I wanted the title to be in all-caps I can do this with swag:

		{{uppercase Title}}

Or if I want to evaluate the data in my flat JSON file, I can run comparisons on my Handlebars templates.

		{{#objects}}
		    {{#is Source 'National Employment Law Project'}}
		        <td>The Source is {{Source}}</td>
		    {{else}}
		        <td>No Source</td>
		    {{/is}}
		{{/objects}}
### Demo: ajax-handlebars

This repo's location has [changed](https://github.com/chrislkeller/projects.chrislkeller.com/tree/master/demos/ajax-handlebars).

以上是关于markdown 在使用AJAX呈现的Handlebars.js模板文件上显示平面JSON文件中的数据。的主要内容,如果未能解决你的问题,请参考以下文章

如何在 GitHub README 中使用 Markdown 呈现多个列?

博客开篇——应用Markdown编辑器呈现样式和内容

是否有用于呈现 GitHub 风格的 Markdown 的命令行实用程序?

在 MVC VIEW 中使用 AngularJS/AJAX 呈现后端数据

如何使用 PHP、cURL、ajax 流式传输实时数据并将其呈现在折线图中

使用 ajax 时,Django 视图不呈现模板