Handlebars使用指南

3,877 阅读3分钟

创建模板

<script id="myTemplate" type="text/x-handlebars-template">
    <div class="entry">
        <h1>{{title}}</h1>
        <div class="body">
            {{body}}
        </div>
    </div>
</script>
  • type类型可以是除text/javascript以外的任何MIME类型,但推荐使用type="text/template",更加语义化
  • id是在后面进行编译的时候所使用,让其编译的代码找到该模板.

渲染模板

var source = $("#myTemplate").html();
var template = Handlebars.compile(source);
var context = {title: "My New Post", body: "This is my first post!"};
var html = template(context);
$('#box').html(html);

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.11/handlebars.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
</head>
<body>
<script id="myTemplate" type="text/x-handlebars-template">
    <div class="entry">
        <h1>{{title}}</h1>
        <div class="body">
            {{body}}
        </div>
    </div>
</script>
<div id="box"></div>
<script>
  var source = $("#myTemplate").html();
  var template = Handlebars.compile(source);
  var context = {title: "My New Post", body: "This is my first post!"};
  var html = template(context);
  $('#box').html(html);
</script>
</body>
</html>

HTML转义

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

块级表达式

<script id="myTemplate" type="text/x-handlebars-template">
    {{#list people}}{{firstName}} {{lastName}}{{/list}}
</script>
<div id="box"></div>
<script>
  var source = $("#myTemplate").html();
  var template = Handlebars.compile(source);
  var context = {
    people: [
      {firstName: "Yehuda", lastName: "Katz"},
      {firstName: "Carl", lastName: "Lerche"},
      {firstName: "Alan", lastName: "Johnson"}
    ]
  };
  Handlebars.registerHelper('list', function(items, options) {
    var out = "<ul>";

    for(var i=0, l=items.length; i<l; i++) {
      out = out + "<li>" + options.fn(items[i]) + "</li>";
    }

    return out + "</ul>";
  });
  var html = template(context);
  $('#box').html(html);
</script>

handlebars路径

<script id="myTemplate" type="text/x-handlebars-template">
    <div class="entry">
        <h1>{{title}}</h1>
        <h2>By {{author.name}}</h2>

        <div class="body">
            {{body}}
        </div>
    </div>
</script>
<div id="box"></div>
<script>
  var source = $("#myTemplate").html();
  var template = Handlebars.compile(source);
  var context = {
    title: "My First Blog Post!",
    author: {
      id: 47,
      name: "Yehuda Katz"
    },
    body: "My first post. Wheeeee!"
  };
  var html = template(context);
  $('#box').html(html);
</script>
{{#with person}}
    <h1>{{../company.name}}</h1>
{{/with}}

{
    "person":
    { "name": "Alan" },
        company:
    {"name": "Rad, Inc." }
};

handlebar内置helper

if

如果变量是false, undefined, null, "", 0, [],将不会渲染

<div class="entry">
  {{#if author}}
    <h1>{{firstName}} {{lastName}}</h1>
  {{/if}}
</div>

unless

和if相反

<div class="entry">
  {{#unless license}}
  <h3 class="warning">WARNING: This entry does not have a license!</h3>
  {{/unless}}
</div>

each

可以用this指代子元素

<ul class="people_list">
  {{#each people}}
    <li>{{this}}</li>
  {{/each}}
</ul>


{
  people: [
    "Yehuda Katz",
    "Alan Johnson",
    "Charles Jolley"
  ]
}

渲染结果是

<ul class="people_list">
  <li>Yehuda Katz</li>
  <li>Alan Johnson</li>
  <li>Charles Jolley</li>
</ul>

可以用else渲染当列表为空时的页面

{{#each paragraphs}}
  <p>{{this}}</p>
{{else}}
  <p class="empty">No content</p>
{{/each}}

如果需要引用列表的索引或者key的话,可以

{{#each array}}
  {{@index}}: {{this}}
{{/each}}

{{#each object}}
  {{@key}}: {{this}}
{{/each}}

value 和 key 别名

{{#each array as |value key|}}
  {{#each child as |childValue childKey|}}
    {{key}} - {{childKey}}. {{childValue}}
  {{/each}}
{{/each}}

with

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

  {{#with author}}
  <h2>By {{firstName}} {{lastName}}</h2>
  {{/with}}
</div>

{
  title: "My first post!",
  author: {
    firstName: "Charles",
    lastName: "Jolley"
  }
}

或者

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

  {{#with author as |myAuthor|}}
  <h2>By {{myAuthor.firstName}} {{myAuthor.lastName}}</h2>
  {{/with}}
</div>

Handlebars自定义helper

<script id="myTemplate" type="text/x-handlebars-template">
    <div class="post">
        <h1>By {{fullName author}}</h1>
        <div class="body">{{body}}</div>

        <h1>Comments</h1>

        {{#each comments}}
        <h2>By {{fullName author}}</h2>
        <div class="body">{{body}}</div>
        {{/each}}
    </div>
</script>
<div id="box"></div>
<script>
  var source = $("#myTemplate").html();
  var template = Handlebars.compile(source);
  var context = {
    author: {firstName: "Alan", lastName: "Johnson"},
    body: "I Love Handlebars",
    comments: [{
      author: {firstName: "Yehuda", lastName: "Katz"},
      body: "Me too!"
    }]
  };

  Handlebars.registerHelper('fullName', function(person) {
    return person.firstName + " " + person.lastName;
  });

  var html = template(context);
  $('#box').html(html);
</script>

可以使用this上下文

<script id="myTemplate" type="text/x-handlebars-template">
    <ul>
        {{#each items}}
        <li>{{agree_button}}</li>
        {{/each}}
    </ul>
</script>
<div id="box"></div>
<script>
  var source = $("#myTemplate").html();
  var template = Handlebars.compile(source);
  var context = {
    items: [
      {name: "Handlebars", emotion: "love"},
      {name: "Mustache", emotion: "enjoy"},
      {name: "Ember", emotion: "want to learn"}
    ]
  };

  Handlebars.registerHelper('agree_button', function() {
    var emotion = Handlebars.escapeExpression(this.emotion),
      name = Handlebars.escapeExpression(this.name);
    console.log(emotion)
    return new Handlebars.SafeString(
      "<button>I agree. I " + emotion + " " + name + "</button>"
    );
  });
  var html = template(context);
  $('#box').html(html);
</script>

模板复用

<script id="myTemplate" type="text/x-handlebars-template">
    <div class="post">
        {{> userMessage tagName="h1" }}

        <h1>Comments</h1>

        {{#each comments}}
        {{> userMessage tagName="h2" }}
        {{/each}}
    </div>
</script>
<div id="box"></div>
<script>
  var source = $("#myTemplate").html();
  var template = Handlebars.compile(source);

  Handlebars.registerPartial('userMessage',
    '<{{tagName}}>By {{author.firstName}} {{author.lastName}}</{{tagName}}>'
    + '<div class="body">{{body}}</div>');
  var context = {
    author: {firstName: "Alan", lastName: "Johnson"},
    body: "I Love Handlebars",
    comments: [{
      author: {firstName: "Yehuda", lastName: "Katz"},
      body: "Me too!"
    }]
  };
  var html = template(context);
  $('#box').html(html);
</script>