iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 4
0
Modern Web

30天快速上手 Meteor - 使用 Universal JavaScript Framework 開發即時聊天大平台系列 第 4

Day03:Blaze/Spacebar 與模板進階使用+搭配 ReactiveVar

昨天介紹了 .onCreated() .onRendered() .onDestroyed 的使用方式與呼叫時機,今天要介紹如何使用 .events().helpers() 並且搭配 ReactiveVar 實現 reactivity。

目前我們透過 hello.js 中的這一行 this.find('#myDiv').innerHTML = this.number; 用命令式(imperativate)的方式來主動更新 div 中的數字,現在試著來改用宣告式(declaritive)的方式來注入數字到到 div 中。

使用 .helpers() 注入資料到模板中

我們可以宣告 helpers object 來幫助我們在模板中注入資料。只要在 Template.模板名稱.helpers() 的括號裡頭傳入 helpers object 即可。

首先我們在 hello.js 移除掉 this.find('#myDiv').innerHTML = this.number; 這兩行:

然後在 hello.js 中新增:

// my-app/client/hello.js
Template.hello.helpers({
	myNumber() {
		return Template.instance().number;
	},
});

便可以在 hello.html 透過 Spacebar 使用 helper:

<!-- my-app/client/hello.html -->
<template name="hello">
  <div id="myDiv">{{myNumber}}</div> <!-- 加入 {{myNumber}} -->
</template>

我們來看看網頁顯示的結果,咦?數字怎麼停在0沒有增加呢?因為 helper 必須依賴於具有 reactivity 的資料才會自動更新,雖然 myNumber 返回了我們一開始預設給模板的數字,但是這個數字不具有 reactivity,即使有改動也不會觸發 myNumber 重新執行。

因此,我們必須使用 ReactiveVar。

使用 ReactiveVar 建立 reactivity data

hello.js 中引入 ReactiveVar,並且將原先的 number 改使用 ReactiveVar 來建立:

// my-app/client/hello.js
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';

Template.hello.onCreated(function() {
	console.log('產生模板..');
	this.timer = null;
    this.number = new ReactiveVar(0); // 建立具 reactivity 的變數,預設值為 0
});

Template.hello.onRendered(function() {
	console.log('顯示模板..');
	this.timer = setInterval(() => {
		const number = this.number.get(); // 透過 .get() 可以取得目前的值
		this.number.set(number + 1);      // 透過 .set() 可以指派新的值
	}, 1000);

    setTimeout(() => {
        Blaze.remove(this.view); 
    }, 5000);
});

Template.hello.onDestroyed(function() {
	console.log('摧毀模板..');
	clearInterval(this.timer);
});

Template.hello.helpers({
	myNumber() { // 依賴於具 reactivity 的變數,當 number 的值改變,這個 helper 會重新執行
		return Template.instance().number.get(); 
	},
});

經過這樣的修改,只要 number 有任何變動,網頁畫面上的數字就會同步更新!

傳入參數給 helper

helper 可以接受參數,例如:

// my-app/client/hello.js
Template.hello.helpers({
	myNumber(initialValue) { 
		return Template.instance().number.get() + initialValue; 
	},
});

而在 Spacebar 中傳入參數的方式很簡單:

<!-- my-app/client/hello.html -->
<template name="hello">
  <div id="myDiv">{{myNumber 5}}</div> <!-- 以空格為間隔,傳入參數 -->
</template>

這樣數字就會從5開始往上增加囉!

使用 .events() 處理網頁互動

為了展示網頁互動的範例,我們先把 timer 的部分移除掉:

// my-app/client/hello.js
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';

Template.hello.onCreated(function() {
	console.log('產生模板..');
    this.number = new ReactiveVar(0); // 建立具 reactivity 的變數,預設值為 0
});

Template.hello.onRendered(function() {
	console.log('顯示模板..');
});

Template.hello.onDestroyed(function() {
	console.log('摧毀模板..');
});

Template.hello.helpers({
	myNumber(initialValue) {
		return Template.instance().number.get() + initialValue; 
	},
});

接著,在 Template.模板名稱.events() 的括號裡頭傳入 event map。event map 透過 object 來定義,由屬性來指定要處理的事件,屬性的值則是處理該事件的 function,而這個 function 具有兩個參數,第一個是事件物件,第二個則是所屬的模板物件。

再來,在 hello.html 新增一個按鈕:

<!-- my-app/client/hello.html -->
<template name="hello">
  <div id="myDiv">{{myNumber}}</div>
  <bbutton id="myButton">加一</button> 
</template>

然後在 hello.js 中新增:

// my-app/client/hello.js
Template.hello.events({
    // 當 id 為 myButton 的元素被點擊時,將 number 加 1
	'click #myButton'(event, templateInstance) { 
		const originalValue = templateInstance.number.get();
        templateInstance.number.set(originalValue + 1);
	},
});

現在只要點擊按鈕,網頁上的數字就會加1囉!

各位對於 .events().helpers() 以及 ReactiveVar 的用法有不清楚或是想更近一步了解的歡迎留言討論喔!明天將會介紹 Spacebar 與 .helpers() 進階搭配用法。


上一篇
Day02:Blaze/Spacebar 與模板基本使用
下一篇
Day04:Blaze/Spacebar 與模板進階使用+重點整理
系列文
30天快速上手 Meteor - 使用 Universal JavaScript Framework 開發即時聊天大平台8
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言