{% raw %}
## 模板
在Meteor中,視圖定義在 _模板_ 。模板就是包含動態數據的HTML代碼段。你可以通過javascript給模板插入數據,或是監聽模板事件。
### 用HTML定義模板
模板定義在`.html`文件中,可以放在項目任何位置,除了`server`,`public`,`private`文件夾
每個`.html`文件可以包含任意數量的頂級元素:`<head>`,`<body>`或是`<template>`。`<head>`,`<body>`標簽里的代碼會附加到HTML頁面中對應的標簽, `<tempalte>`標簽里的代碼可以用`{{> templateName}}`引入,如下面的例子所示。模板可以引入多次—模板的主要目的之一就是避免重復手寫相同的HTML。
```
<!-- add code to the <head> of the page -->
<head>
<title>My website!</title>
</head>
<!-- add code to the <body> of the page -->
<body>
<h1>Hello!</h1>
{{> welcomePage}}
</body>
<!-- define a template called welcomePage -->
<template name="welcomePage">
<p>Welcome to my website!</p>
</template>
```
`{{ ... }}`是Spacebars語法,Meteor使用Spacebars給HTML增加功能。如上所示,利用它你可以引入模板。 使用Spacebars,你可以顯示從 _helpers_ 中獲取的數據。Helpers 用javascript來寫,既可以是簡單值,也可以是函數。
### [_Template.myTemplate_.helpers(helpers)](#/basic/Template-helpers)
Client
Specify template helpers available to this template.
#### Arguments
helpers Object
Dictionary of helper functions by name.
給`nametag`模板定義一個叫做`name`的helper(在javascript里):
```
Template.nametag.helpers({
name: "Ben Bitdiddle" });
```
`nametag` 模板本身 (在HTML里):
```
<!-- In an HTML file, display the value of the helper -->
<template name="nametag">
<p>My name is {{name}}.</p>
</template>
```
Spacebars還有幾個方便使用的控制結構,可以使視圖更加動態:
* `{{#each data}} ... {{/each}}` - 循環`data`里的每一項,每一項都會顯示一次`#each`塊里的HTML。
* `{{#if data}} ... {{else}} ... {{/if}}` - 如果`data`為`true`,顯示第一個塊,反之,顯示第二個塊。
* `{{#with data}} ... {{/with}}` - 設置內部HTML的數據上下文,然后顯示。
每一個嵌套的`#each`或`#with`塊都有自己的 _數據上下文_ ,數據上下文是一個對象,它的屬性在塊內部可以用作helper。例如:`#with`塊,它的數據上下文就是跟在它后面,`}}`之前的變量值。`#each`塊,循環到的元素會作為當前數據上下文。
例如,`people` helper 的值為:
```
Template.welcomePage.helpers({
people: [{name: "Bob"}, {name: "Frank"}, {name: "Alice"}]
});
```
然后你可以用一個`<p>`標簽列表顯示每一個人的姓名:
```
{{#each people}}
<p>{{name}}</p>
{{/each}}
```
或是用上面的"nametag"模板代替 `<p>`標簽:
```
{{#each people}}
{{> nametag}}
{{/each}}
```
記住:helper可以是簡答值,也可以是函數。例如,要顯示登錄用戶的用戶名,你可以定義一個叫做`username`的helper:
```
// in your JS file
Template.profilePage.helpers({
username: function () {
return Meteor.user() && Meteor.user().username;
}
});
```
現在,每次使用`username` helper的時候,都會調用上面的helper函數來確定用戶名:
```
<!-- in your HTML -->
<template name="profilePage">
<p>Profile page for {{username}}</p>
</template>
```
Helper可以接收參數。例如,
```
Template.post.helpers({
commentCount: function (numComments) {
if (numComments === 1) {
return "1 comment";
} else {
return numComments + " comments";
}
}
});
```
參數放在大括號里,helper名之后:
```
<p>There are {{commentCount 3}}.</p>
```
上面定義的helper都關聯到特定的模板,可以用[`Template.registerHelper`](#template_registerhelper)定義所有模板都能用的helper。
關于Spacebars更詳細的文檔參見[README on GitHub](https://github.com/meteor/meteor/blob/devel/packages/spacebars/README.md)。后面的`Session`, `Tracker`,`Collections`, 和 `Accounts`小節會有如何給模板添加動態數據的討論。
### [_Template.myTemplate_.events(eventMap)](#/basic/Template-events)
Client
Specify event handlers for this template.
#### Arguments
eventMap [Event Map](#eventmaps)
Event handlers to associate with this template.
傳給`Template.myTemplate.events`的事件map,用事件描述符作為key,事件處理函數作為value。事件處理函數接收兩個參數:事件對象和模板實例。事件處理函數中通過`this`獲取數據上下文。
假設有下面的模板:
```
<template name="example">
{{#with myHelper}}
<button class="my-button">My button</button>
<form>
<input type="text" name="myInput" />
<input type="submit" value="Submit Form" />
</form>
{{/with}}
</template>
```
調用 `Template.example.events` 給模板增加事件處理器:
```
Template.example.events({
"click .my-button": function (event, template) {
alert("My button was clicked!");
},
"submit form": function (event, template) {
var inputValue = event.target.myInput.value;
var helperValue = this;
alert(inputValue, helperValue);
}
});
```
key的前半部分是要捕獲的事件名稱。幾乎支持所有的DOM事件,常見的有:`click`, `mousedown`, `mouseup`, `mouseenter`, `mouseleave`, `keydown`, `keyup`, `keypress`, `focus`, `blur`, 和 `change`。
key的后半部分是CSS選擇器,用來指明要監聽的元素。幾乎支持所有[JQuery支持的選擇器](http://api.jquery.com/category/selectors/).
無論何時,選定元素上觸發了監聽的事件時,對應的事件處理函數就會被調用,參數為:DOM 事件對象和模板實例。詳細信息參見[Event Maps section](#eventmaps)
### [_Template.myTemplate_.onRendered](#/basic/Template-onRendered)
Client
Register a function to be called when an instance of this template is inserted into the DOM.
#### Arguments
callback Function
A function to be added as a callback.
用這個方法注冊的函數會在_Template.myTemplate_模板的每個實例第一次插入到頁面的時候調用一次。
這個回調函數可以用來集成那些不適應Meteor自動視圖渲染機制,并且需要在每次HTML插入到頁面時進行初始化的第三方庫。 你可以在[`onCreated`](#template_oncreated) 和 [`onDestroyed`](#template_ondestroyed)回調中執行對象初始化或是清理工作。
例如,要使用HighlightJS庫高亮`codeSample`模板中所有`<pre>`元素,你可以傳遞如下回調函數給 `Template.codeSample.onRendered`:
```
Template.codeSample.onRendered(function () {
hljs.highlightBlock(this.findAll('pre'));
});
```
在回調函數中,`this`指向一個[template instance](#template_inst)對象實例,that is unique to this inclusion of the template and remains across re-renderings.可以使用方法[`this.find`](#template_find) 和 [`this.findAll`](#template_findAll)來獲取模板渲染后的HTML DOM節點。
{% endraw %}