如果說集合是 Meteor 的核心功能,那么響應(yīng)式可以能讓這個核心功能更強大。
集合從根本上改變你的應(yīng)用程序的數(shù)據(jù)處理方式。從而不必手動檢查數(shù)據(jù)更改(例如,通過一個 AJAX 調(diào)用),再根據(jù)這些變化去修改 HTML 頁面,Meteor 可以隨時檢測到數(shù)據(jù)的更改,并將它無縫地應(yīng)用到你的用戶界面上。
讓我們思考一下:在后臺,當(dāng)?shù)讓拥臄?shù)據(jù)集合被更新以后, Meteor 能夠馬上修改用戶界面的任何部分。
這個實時性的方法是通過使用 .observe()
,當(dāng)指向數(shù)據(jù)的指針發(fā)生改變時就會觸發(fā)回調(diào)。我們可以通過這些回調(diào)去更改 DOM (我們的網(wǎng)頁呈現(xiàn)的 HTML )。就像這樣的代碼:
Posts.find().observe({
added: function(post) {
// when 'added' callback fires, add HTML element
$('ul').append('<li id="' + post._id + '">' + post.title + '</li>');
},
changed: function(post) {
// when 'changed' callback fires, modify HTML element's text
$('ul li#' + post._id).text(post.title);
},
removed: function(post) {
// when 'removed' callback fires, remove HTML element
$('ul li#' + post._id).remove();
}
});
可能你已經(jīng)知道這樣的代碼是如何把復(fù)雜的事情快速地進(jìn)行處理。想象一下如果我們?nèi)バ薷奶拥?strong>任何一個屬性,就會伴隨著頁面中帖子 <li>
標(biāo)簽的更改。當(dāng)我們開始依賴于更多個數(shù)據(jù)信息的時候,甚至還可以進(jìn)行更為復(fù)雜的處理,這些都能實時地進(jìn)行。
使用上述的模式有時候很有必要的,尤其是在處理第三方小部件的時候。比如,假設(shè)我們想要基于集合數(shù)據(jù)去實時添加或刪除在地圖上的位置(也就是說顯示當(dāng)前登錄用戶的位置)。
在這種情況下,為了讓地圖能跟 Meteor 的集合進(jìn)行“交談”,你就需要使用 observe()
的回調(diào)方法去應(yīng)對數(shù)據(jù)變化。例如,你需要依賴其中 added
和 removed
的回調(diào)方法去調(diào)用地圖 API 中的 dropPin()
或 removePin()
方法。
Meteor 為我們提供了一個更好的辦法:聲明式方法,它的核心就是響應(yīng)式。這種聲明讓我們定義了對象之間的關(guān)系,并讓他們保持同步,而我們就不必為每個的可能發(fā)生的修改去指定相應(yīng)的行為。
這是一個強大的概念,因為有許多實時性的輸入,都可能發(fā)生在我們不可預(yù)測的時間中。通過聲明式方法去聲明我們該如何基于響應(yīng)式數(shù)據(jù)去呈現(xiàn) HTML ,這樣 Meteor 就可以完成對這些數(shù)據(jù)的監(jiān)控工作,并且把用戶界面直接與數(shù)據(jù)進(jìn)行綁定。
總的來說,去代替 observe
的回調(diào),Meteor 可以讓我們這些寫:
<template name="postsList">
<ul>
{{#each posts}}
<li>{{title}}</li>
{{/each}}
</ul>
</template>
然后獲取我們的帖子列表:
Template.postsList.helpers({
posts: function() {
return Posts.find();
}
});
在后臺,其實 Meteor 替我們使用了 observe()
的回調(diào)方法,并當(dāng)響應(yīng)式數(shù)據(jù)被更改的時候,對相關(guān)頁面進(jìn)行重新的渲染。
Meteor 是一個實時性、響應(yīng)式的框架,但并不是所有的代碼在 Meteor App 里面都是響應(yīng)式的。如果是這樣,當(dāng)有任何數(shù)據(jù)發(fā)生改變時,你的 App 都會自動進(jìn)行重新運行。相反,響應(yīng)式只是在特定區(qū)域的代碼中發(fā)生,我們稱這些區(qū)域為 Computations 。
換句話說, Computations 代碼塊是根據(jù)響應(yīng)式數(shù)據(jù)的變化去運行。如果你有一個響應(yīng)式數(shù)據(jù)源(例如,一個 Session 變量)并且希望及時去響應(yīng)它,你需要建立一個 Computations。
請注意,你一般不需要顯式地做到這一點,因為 Meteor 已經(jīng)讓每個模板去呈現(xiàn)它自己的 Computation (意思就是模板 Helper 中的代碼和回調(diào)函數(shù)默認(rèn)都是響應(yīng)式的)。
Computations 用到的響應(yīng)式數(shù)據(jù)源都會被它跟蹤,這樣就可以知道響應(yīng)式數(shù)據(jù)什么時候發(fā)生變化。這是通過 Computations 中的 invalidate()
方法實現(xiàn)的。
Computations 一般只是簡單地用來判斷頁面上的無效內(nèi)容,這通常是發(fā)生在模板的 Computations(盡管模板 Computations 可能也會去做一些讓頁面更有效的工作)。當(dāng)然如果你需要,你也可以使用更多 Computations 的功能,不過在實際中可能比較少用到。
現(xiàn)在我們?nèi)ダ斫庖幌?Computations 背后的工作原理,實際上要設(shè)置一個 Computations 是出乎意料的簡單。我們只需要在 Tracker.autorun
方法中加上需要的代碼塊,讓它變成響應(yīng)式的 Computations :
Meteor.startup(function() {
Tracker.autorun(function() {
console.log('There are ' + Posts.find().count() + ' posts');
});
});
注意我們需要把 Tracker
代碼塊放進(jìn) Meteor.startup()
塊中,來確保它在 Meteor 完成加載 Posts
集合后只運行一次。
在后臺,autorun
會創(chuàng)建一個 Computation ,當(dāng)數(shù)據(jù)源發(fā)生變化的時候就會自動重新運行。這樣我們就建立了一個非常簡單的 Computation ,去把帖子的數(shù)量輸出到控制臺上。因為 Posts.find()
是一個響應(yīng)式數(shù)據(jù)源,它將負(fù)責(zé)告訴 Computation 每次帖子數(shù)量發(fā)生變化的時候去重新運行。
> Posts.insert({title: 'New Post'});
There are 4 posts.
綜上所述,我們可以把響應(yīng)式數(shù)據(jù)通過一種很自然的方式與代碼進(jìn)行綁定,這樣后臺的依賴系統(tǒng)將會在合適的時間去重新運行這段代碼。
更多建議: