Edited at

Meteorのあんちょこ꒰。・ω・`;꒱ テンプレート編

More than 1 year has passed since last update.


本流


テンプレート


概要


  • テンプレートは、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


.meteor/packages

blaze-html-templates    # Compile .html files into Meteor Blaze views



client/main.html

<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>



client/main.js

// 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構造


client/main.html

  {{> 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>



client/main.js

Template.family.helpers({

person: { name: 'Shoko JP' },
family : {
lastname: 'JP',
mother: { name:'Hanako' },
father: { name:'Taro' }
},
});


分岐(if)


client/main.html

  <h2>ifで記述</h2>

<p>{{> current_time}}</p>

<template name="current_time">
{{# if oddSeconds}}
現在時刻は{{dateString}}
{{else}}
現在時刻は{{now}}
{{/if}}
</template>



client/main.js

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;
}
});


client/main.html

  {{> 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)


client/main.html

  <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秒



client/main.js

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)


client/main.html

  <h2>eachで記述(デフォルトの昇順ループ)</h2>

{{> fruits }}
<template name="fruits">
<ul>
{{ #each fruits }}
<li>{{this}}</li>
{{ /each }}
</ul>
</template>


client/main.js

Template.fruits.helpers({

fruits: ['apple', 'banana', 'orange']
});


eachで記述(デフォルトの昇順ループ)

* apple

* banana

* orange



代入(let)


client/main.html

  <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>



client/main.js

Template.sample_let.helpers({

person: {
bio: { firstName: 'Shoko' }
},
generateColor: 'red'
});


letで記述

Shoko gets a red card!



自作のBlock Helper


  • TODO:要調査



テンプレートでのイベント処理


参考


Sample


  • template-events


イベント定義


  • イベントマップキーは下記の形式で指定する。


イベント名[,イベント名...] セレクタ



main.html

<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>



main.js

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…テンプレートが破棄された時に呼び出されるイベントハンドラ。



main.js

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という概念の理解が必要。)


main.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>



main.js

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


パッケージ追加


console

$ meteor add dbernhard:jquery-ui-draggable



コーディング


main.html

<template name="test">

<article class="article">Draggable Element</article>
</template>


main.js

Template.test.onRendered(function testOnRendered() {

$article = $(Template.instance().firstNode);
$article.draggable();
// console.log($article);
});