LoginSignup
5
6

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-07-11

本流

テンプレート

概要

  • テンプレートは、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);
});
5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6