Meteor 響應(yīng)式

2022-06-30 13:57 更新

響應(yīng)式

如果說集合是 Meteor 的核心功能,那么響應(yīng)式可以能讓這個(gè)核心功能更強(qiáng)大。

集合從根本上改變你的應(yīng)用程序的數(shù)據(jù)處理方式。從而不必手動(dòng)檢查數(shù)據(jù)更改(例如,通過一個(gè) AJAX 調(diào)用),再根據(jù)這些變化去修改 HTML 頁面,Meteor 可以隨時(shí)檢測(cè)到數(shù)據(jù)的更改,并將它無縫地應(yīng)用到你的用戶界面上。

讓我們思考一下:在后臺(tái),當(dāng)?shù)讓拥臄?shù)據(jù)集合被更新以后, Meteor 能夠馬上修改用戶界面的任何部分。

這個(gè)實(shí)時(shí)性的方法是通過使用 .observe() ,當(dāng)指向數(shù)據(jù)的指針發(fā)生改變時(shí)就會(huì)觸發(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>任何一個(gè)屬性,就會(huì)伴隨著頁面中帖子 <li> 標(biāo)簽的更改。當(dāng)我們開始依賴于更多個(gè)數(shù)據(jù)信息的時(shí)候,甚至還可以進(jìn)行更為復(fù)雜的處理,這些都能實(shí)時(shí)地進(jìn)行。

我們應(yīng)該什么時(shí)候去使用 observe()?

使用上述的模式有時(shí)候很有必要的,尤其是在處理第三方小部件的時(shí)候。比如,假設(shè)我們想要基于集合數(shù)據(jù)去實(shí)時(shí)添加或刪除在地圖上的位置(也就是說顯示當(dāng)前登錄用戶的位置)。

在這種情況下,為了讓地圖能跟 Meteor 的集合進(jìn)行“交談”,你就需要使用 observe() 的回調(diào)方法去應(yīng)對(duì)數(shù)據(jù)變化。例如,你需要依賴其中 addedremoved 的回調(diào)方法去調(diào)用地圖 API 中的 dropPin()removePin() 方法。

聲明式方法

Meteor 為我們提供了一個(gè)更好的辦法:聲明式方法,它的核心就是響應(yīng)式。這種聲明讓我們定義了對(duì)象之間的關(guān)系,并讓他們保持同步,而我們就不必為每個(gè)的可能發(fā)生的修改去指定相應(yīng)的行為。

這是一個(gè)強(qiáng)大的概念,因?yàn)橛性S多實(shí)時(shí)性的輸入,都可能發(fā)生在我們不可預(yù)測(cè)的時(shí)間中。通過聲明式方法去聲明我們?cè)撊绾位陧憫?yīng)式數(shù)據(jù)去呈現(xiàn) HTML ,這樣 Meteor 就可以完成對(duì)這些數(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();
  }
});

在后臺(tái),其實(shí) Meteor 替我們使用了 observe() 的回調(diào)方法,并當(dāng)響應(yīng)式數(shù)據(jù)被更改的時(shí)候,對(duì)相關(guān)頁面進(jìn)行重新的渲染。

Meteor 的依賴跟蹤:Computations

Meteor 是一個(gè)實(shí)時(shí)性、響應(yīng)式的框架,但并不是所有的代碼在 Meteor App 里面都是響應(yīng)式的。如果是這樣,當(dāng)有任何數(shù)據(jù)發(fā)生改變時(shí),你的 App 都會(huì)自動(dòng)進(jìn)行重新運(yùn)行。相反,響應(yīng)式只是在特定區(qū)域的代碼中發(fā)生,我們稱這些區(qū)域?yàn)?Computations 。

換句話說, Computations 代碼塊是根據(jù)響應(yīng)式數(shù)據(jù)的變化去運(yùn)行。如果你有一個(gè)響應(yīng)式數(shù)據(jù)源(例如,一個(gè) Session 變量)并且希望及時(shí)去響應(yīng)它,你需要建立一個(gè) Computations。

請(qǐng)注意,你一般不需要顯式地做到這一點(diǎn),因?yàn)?Meteor 已經(jīng)讓每個(gè)模板去呈現(xiàn)它自己的 Computation (意思就是模板 Helper 中的代碼和回調(diào)函數(shù)默認(rèn)都是響應(yīng)式的)。

Computations 用到的響應(yīng)式數(shù)據(jù)源都會(huì)被它跟蹤,這樣就可以知道響應(yīng)式數(shù)據(jù)什么時(shí)候發(fā)生變化。這是通過 Computations 中的 invalidate() 方法實(shí)現(xiàn)的。

Computations 一般只是簡(jiǎn)單地用來判斷頁面上的無效內(nèi)容,這通常是發(fā)生在模板的 Computations(盡管模板 Computations 可能也會(huì)去做一些讓頁面更有效的工作)。當(dāng)然如果你需要,你也可以使用更多 Computations 的功能,不過在實(shí)際中可能比較少用到。

建立一個(gè) Computations

現(xiàn)在我們?nèi)ダ斫庖幌?Computations 背后的工作原理,實(shí)際上要設(shè)置一個(gè) Computations 是出乎意料的簡(jiǎn)單。我們只需要在 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 集合后只運(yùn)行一次。

在后臺(tái),autorun 會(huì)創(chuàng)建一個(gè) Computation ,當(dāng)數(shù)據(jù)源發(fā)生變化的時(shí)候就會(huì)自動(dòng)重新運(yùn)行。這樣我們就建立了一個(gè)非常簡(jiǎn)單的 Computation ,去把帖子的數(shù)量輸出到控制臺(tái)上。因?yàn)?Posts.find() 是一個(gè)響應(yīng)式數(shù)據(jù)源,它將負(fù)責(zé)告訴 Computation 每次帖子數(shù)量發(fā)生變化的時(shí)候去重新運(yùn)行。

> Posts.insert({title: 'New Post'});
There are 4 posts.

綜上所述,我們可以把響應(yīng)式數(shù)據(jù)通過一種很自然的方式與代碼進(jìn)行綁定,這樣后臺(tái)的依賴系統(tǒng)將會(huì)在合適的時(shí)間去重新運(yùn)行這段代碼。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)