[cookbook] Meteor Template (그냥 template engine이 아니다. Mongodb와 밀접하게 연관된 Template)

Meteor Template Introduction

TemplateCollection 기능만 알면 meteor의 기능을 50% 활용할 수 있다고 생각합니다. 실제 meteor example application 을 보더라도 Template와 Collection 사용부분이 많은 영역을 차지합니다. 그럼 시작해보겠습니다. 참고로 이글은 template engine에 대해서 알고 있다는 전제입니다.

template

Feature

사용순서

Template Global Object

HTML에 아래와 같이 정의하였다고 가정합니다.

<template name="Name">
  <div class="foo">{{bar}}</div>
</template>

Template API 는 현재 meteor doc에 정확히 정의가 안되어 있으나, 사용하시기에는 어려움이 없을것입니다. 하나하나 짚어나가겠습니다.

접근 / 치환

Template.TName 말그대로 <template name="TName">~</template> 해당 Element의 name을 지정하여 접근하고 치환할 수 있습니다.

Syntax

Template.TName(Object);

Argument

치환할 대상을 지정한 key값에 대응하는 object를 정의합니다.

Template.TName({bar: "baz"});
=> "<div class="foo">baz</div>"

nested 접근 / Data Bind

Template.TName 말그대로 <template name="TName">~</template> 해당 Element의 name을 지정하여 접근하고 template 안에서 지정한 {{ ~ }} 치환자에 Data (Collection, Sesssion)bind 할 수 있습니다.

Syntax

Template.TName.치환자_키명 = Function;

Example

HTML 에 아래와 같이 지정하고,

<template name="leaderboard">  
  <div>    
    {{#each players}}          

    {{/each}}                  
  </div>                       
</template>

JS 에 아래와 같이 정의합니다.

//
// template name이 leaderboard 에 접근하고,
// players 치환자에 function을 지정하며
// 그 function의 return 값은 Collection cursor 입니다.
//
Template.leaderboard.players = function () {
  return Players.find({}, {sort: {score: -1, name: 1}});
};

nested 접근 / Event Bind

Template.TName 말그대로 <template name="TName">~</template> 해당 Element의 name을 지정하여 접근하고, template 안에서 지정한 {{ ~ }} 치환자에 Event (click …)bind 할 수 있습니다.

Syntax

Template.Name.events = EventObject;

EventObject 지정방법은 이전 편에서도 많이 알려드렸고, 정확한 문서는 이곳을 참조하시기 바랍니다.

Example

HTML 에 아래와 같이 지정합니다. {{> player}} 같은 부분이 추가되었는데, partial 이라는 치환자입니다. 이것의 기능은 다른 template Element를 불러올 수 있는 기능입니다. include 라고 생각하시면 됩니다.

<template name="leaderboard">  
  <div>    
    {{#each players}}          
    {{> player}}
    {{/each}}                  
  </div>                       
</template>

<!--
partial에 해당하는 template
위 예제에서 data bind 하였는데, data 의 키값은 name, score로 이루어져 있습니다. 
-->
<template name="player">                
  <div>     
    <span class="name">{{name}}</span>  
    <span class="score">{{score}}</span>
  </div>                                
</template>                             

JS 에 아래와 같이 정의합니다.

//
// player template 에 접근하여 events 를 선언합니다.
//
Template.player.events = {
  'click': function () {
    console.log('event delegation 적용되었다.')
  }
};

이 전편을 읽으신 분들은 Meteor.ui.render의 기능이 Template Element와 Template Object 으로 동일한 효과를 낼 수 있다는것을 알아채실 것입니다. 즉, 다이나믹하게 UI를 컨트롤 하고 싶을때는 Meteor.ui부분을 보면 되고, 정적인 구조를 만들고 싶을때는 이번편을 참고하시면 됩니다.

Meteor.ui 와 연동

//
// 이전편에 설명했듯이
// Meteor.ui.render 의 반환값은 DocumentFragment 라는것을 잊지 마세요.
//
var frag = Meteor.ui.render(function () {
  //
  // hello name을 가진 Template 에
  // first, last 키값을 가진 치환자에 값을 대입한 후
  // render에 반환합니다.
  //
  return Template.hello({first: "Alyssa", last: "Hacker"});
});

Meteor.ui / Session 과 연동

in html

//
// forecast name을 가진 Template 를 선언합니다.
//
<template name="forecast">
  //
  // prediction 치환자를 선언합니다.
  //
  <div>It'll be {{prediction}} tonight</div>
</template>

in js

//
// nested 접근합니다.
// forecast Template에 접근하고,
// prediction 치환자에 Data 를 bind 합니다.
// 여기서 Data 는 Session 이네요.
//
Template.forecast.prediction = function () {
  //
  // weather 세션키값을 가져옵니다.
  // 
  return Session.get("weather");
};

firebug 에 아래와 같이 바로 브라우져에서 확인할 수 있도록 실행해봅니다.
일단 weather 세션키값을 cloudy 라고 선언합니다.

> Session.set("weather", "cloudy");

forecast name을 가진 Template를 Meteor.ui.render 에게 넘기고, 반환되는 DocumentFragment 를 appendChild에거 넘깁니다. 화면에 표시되갰죠.

> document.body.appendChild(Meteor.ui.render(Template.forecast));

//
// 아래와 같이 보일것입니다.
//
In DOM:  <div>It'll be cloudy tonight</div>

그럼, Bind된 Data가 reactivity되는 모습을 확인해보겠습니다.

> Session.set("weather", "cool and dry");

Data를 변경하자마자 아래와 같이 변경된 값으로 반영됩니다.

In DOM:  <div>It'll be cool and dry tonight</div>

Conclusion

이게 전부입니다. 굉장히 심플하고 사용하기 쉽고, 여기다가 Mongodb에 저장된 Data까지 reactivity하게 적용되니 굉장히 융통성있는 개발을 할 수 있을것입니다. 그럼 이것으로 줄이겠습니다. 감사합니다.

추천 관련글