本流
テンプレート
概要
- テンプレートは、Handlebarsで記述する。
- Blazeはレンダリングライブラリらしい。
- レンダリングを、Blazeのかわりに、React.jsやAngular.jsに担当してもいいが、Blazeが最良と書いてあるので、鵜呑みにする。。。
Blaze is Meteor’s built-in reactive rendering library. Usually, templates are written in Spacebars...
Blaze is not required to build applications in Meteor—you can also easily use React or Angular to develop your UI (here’s a comparison). However, this particular article will take you through best practices in building an application in Blaze, which is used as the UI engine in all of the other articles.
- Meteorは要素によって定義されたテンプレートを、JavaScriptコードにコンパイルして利用する。
- 開発モードで動作させる場合は、コンパイル処理を実行時に、本番環境ではコンパイル処理は事前に実施する。
- コンパイルで、テンプレートはJavaScriptの関数となる。
グローバルなTemplateオブジェクトのメンバーとして定義される。その関数に対しては,Template.テンプレート名でアクセスすることが可能。- 参考文献と異なり、**Template.(テンプレート名)**の場合、テンプレートオブジェクトが参照可。
- Template.(テンプレート名).renderFunction().valueで表示内容にアクセス可。
- 経験則的な為、手段として正しいかどうかは、自信なし。
> Template.mainContent
Template {viewName: "Template.mainContent", renderFunction: function, __helpers: HelperMap, __eventMaps: Array, _callbacks: {created: [], rendered: [], destroyed: []}, …} = $1
> Template.mainContent.renderFunction().value
< "<button id=\"hello\">Hello</button>" = $8
参考
埋込み用のエスケープ記号
- {{text}}...テキストを埋める場合は2重中括弧で記述
- {{{html}}}...HTMLを埋める場合は3重中括弧で記述
参考:Insert HTML markup using Meteor@stack overflow
Sample
- template
- blaze
My first sample
blaze-html-templates # Compile .html files into Meteor Blaze views
<head>
<title>template</title>
</head>
<body>
<h1>Welcome to Meteor!</h1>
{{> sample1}}
{{> sample2}}
{{> welcome yourname="Shoko" now="2016-07-01"}}
{{> welcomeja }}
</body>
<template name="sample1">
<p>This is my first template1...</p>
</template>
<template name="sample2">
<p>This is my first template2...</p>
</template>
<template name="welcome">
<p>Hello, {{yourname}}. Now is {{now}}.</p>
</template>
<template name="welcomeja">
<p>Hello, {{yourname}}. Now is {{now}}.</p>
</template>
<template name="greet" greeting="Hello, <br>Shoko">
<p>Hello, {{{greeting}}}.</p>
</template>
// helpers関数を使って、テンプレート評価できた。
Template.welcomeja.helpers({
yourname: 'Shoko',
now: new Date()
});
ようこそ、Shoko. 現在時刻はTue Jul 12 2016 05:27:11 GMT+0900 (JST)
Built-in Block Helper (ブロック構造)
DOM構造
{{> family}}
:
<template name="family">
<p>ようこそ、{{person.name}}.</p>
{{#with family}}
<p>苗字は{{lastname}}。</p>
{{#with mother}}
<p>母は、{{name}}</p>
<p>父は、{{../father.name}}</p>
{{/with}}
{{/with}}
</template>
Template.family.helpers({
person: { name: 'Shoko JP' },
family : {
lastname: 'JP',
mother: { name:'Hanako' },
father: { name:'Taro' }
},
});
分岐(if)
<h2>ifで記述</h2>
<p>{{> current_time}}</p>
<template name="current_time">
{{# if oddSeconds}}
現在時刻は{{dateString}}
{{else}}
現在時刻は{{now}}
{{/if}}
</template>
Template.current_time.helpers({
now: new Date(),
oddSeconds: function () {
var date = new Date();
//console.log(date.getSeconds());
return date.getSeconds() % 2 === 1;
},
dateString: function () {
var date = new Date();
var date_ja = date.getFullYear() + '年' + (date.getMonth() + 1) + '月' + date.getDate() + '日 ' +
date.getHours() + '時' + date.getMinutes() + '分' + date.getSeconds() + '秒';
return date_ja;
}
});
{{> caller_myif}}
<template name="myIf">
{{#if condition}}
{{> Template.contentBlock}}
{{else}}
{{> Template.elseBlock}}
{{/if}}
</template>
<template name="caller_myif">
{{#myIf condition=true}}
<h1>I'll be rendered!</h1>
{{else}}
<h1>I won't be rendered</h1>
{{/myIf}}
</template>
I'll be rendered!
分岐(unless)
<h2>unlessで記述</h2>
<p>{{> current_time_unless}}</p>
<template name="current_time_unless">
{{# unless oddSeconds}}
<span style="color:green">現在時刻は{{dateString}}</span>
{{else}}
<span style="color:red">現在時刻は{{now}}</span>
{{/unless}}
</template>
ifで記述
現在時刻は2016年7月12日 6時48分55秒
Template.current_time_unless.helpers({
now: new Date(),
oddSeconds: function () {
var date = new Date();
//console.log(date.getSeconds());
return date.getSeconds() % 2 === 1;
},
dateString: function () {
var date = new Date();
var date_ja = date.getFullYear() + '年' + (date.getMonth() + 1) + '月' + date.getDate() + '日 ' +
date.getHours() + '時' + date.getMinutes() + '分' + date.getSeconds() + '秒';
return date_ja;
}
});
unlessで記述
現在時刻はTue Jul 12 2016 06:48:55 GMT+0900 (JST)
ループ(each)
<h2>eachで記述(デフォルトの昇順ループ)</h2>
{{> fruits }}
<template name="fruits">
<ul>
{{ #each fruits }}
<li>{{this}}</li>
{{ /each }}
</ul>
</template>
Template.fruits.helpers({
fruits: ['apple', 'banana', 'orange']
});
eachで記述(デフォルトの昇順ループ)
- apple
- banana
- orange
代入(let)
<h2>letで記述</h2>
<p>{{> sample_let }}</p>
<template name="sample_let">
{{#let name=person.bio.firstName color=generateColor}}
<div>{{name}} gets a {{color}} card!</div>
{{/let}}
</template>
Template.sample_let.helpers({
person: {
bio: { firstName: 'Shoko' }
},
generateColor: 'red'
});
letで記述
Shoko gets a red card!
自作のBlock Helper
- TODO:要調査
テンプレートでのイベント処理
参考
Sample
- template-events
イベント定義
- イベントマップキーは下記の形式で指定する。
イベント名[,イベント名...] セレクタ
<head>
<title>template-events</title>
</head>
<body>
<h1>Welcome to Meteor!</h1>
{{> mainContent}}
</body>
<template name="mainContent">
<button id="hello">Hello</button>
<button id="goodMorning">Good Morning</button>
</template>
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import './main.html';
Template.mainContent.helpers({
});
Template.mainContent.events({
'click button'(event, instance) {
alert("Button Clicked");
},
'click #hello' (event, instance) {
alert("Hello");
},
'click #goodMorning' (event, instance) {
alert("Good Morning");
}
});
テンプレートAPI
- 要素はMeteorによってコンパイルされ、グローバル変数Templateに関数オブジェクトとして登録される。
イベントハンドラ
-
Template関数オブジェクトには下記のイベントを常備されている。
-
onCreated…テンプレートが生成時に呼び出されるイベントハンドラ
-
onRendered…テンプレートの実行結果がDOM展開時呼び出されるイベントハンドラ(表示時と考えると分かりやすいが、非表示オブジェクトもあるので、展開としておく。)
-
onDestroyed…テンプレートが破棄された時に呼び出されるイベントハンドラ。
Template.mainContent.onCreated(function () {
console.log('created');
});
Template.mainContent.onRendered(function() {
console.log('rendered');
});
Template.mainContent.onDestroyed(function() {
console.log('destroyed');
});
関数
- events(event map)…イベントマップ
- helpers(helpers)…ヘルパー関数(テンプレートにデータを受け渡す。)
- preserve(selectors)…テンプレートの再レンダリングが行われた際、以前のDOMノードの状態を引き継ぎたい要素を、セレクタで指定します。(テンプレートの再レンダリングについては、ライブHTMLという概念の理解が必要。)
<head>
<title>template-events</title>
</head>
<body>
<h1>Welcome to Meteor!</h1>
{{> mainContent}}
</body>
<template name="mainContent">
<button id="hello" class="greetings">Hello</button>
<button id="goodMorning" class="greetings">Good Morning</button>
<hr/>
<input type="text" id="name"/><button id="greet">greet</button>
</template>
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import './main.html';
Template.mainContent.helpers({
});
Template.mainContent.events({
'click button .greetings'(event, template) {
alert("Button Clicked");
console.log(template);
console.log(template.firstNode);
console.log(template.lastNode);
console.log(template.findAll('button')); // 検索にヒットするすべてのノード
console.log(template.find('button')); // 検索にヒットする最初のノード
console.log(template.$('button')); // jquery
// console.log(template.data()); // テンプレートが呼び出された際に渡されたデータ
},
'click #hello' (event, template) {
alert("Hello");
},
'click #goodMorning' (event, template) {
alert("Good Morning");
},
'click #greet' (event, template) {
var name = template.$('input[type=text]').val(); //jquery
//var name = template.find('input[type=text]').value; //DOM
console.log(name);
}
});
Template.mainContent.onCreated(function () {
console.log('created');
var template = this;
console.log(template);
});
Template.mainContent.onRendered(function() {
console.log('rendered');
});
Template.mainContent.onDestroyed(function() {
console.log('destroyed');
});
JQuery UI Draggableを使用してみた
Sample
- sample_draggble
パッケージ追加
- Atmosphereでパッケージを検索できる。
- dbernhard:jquery-ui-draggableを導入する。
$ meteor add dbernhard:jquery-ui-draggable
コーディング
<template name="test">
<article class="article">Draggable Element</article>
</template>
Template.test.onRendered(function testOnRendered() {
$article = $(Template.instance().firstNode);
$article.draggable();
// console.log($article);
});