2015-05-30 70 views
25

Tracker方法並不完全屬於Meteor的核心功能,很少用於教程和初學者書籍(如果它們不是很好解釋的話),因此被認爲更加「可怕」比大多數框架的其餘部分。例如,我從來沒有設法將Tracker.autorun轉換成我的項目,因爲它似乎沒有做到它所期望的那樣。這就是文檔所說的:用簡單的英文,Tracker.autorun做什麼?

現在運行一個函數,稍後當其依賴項 更改時重新運行。

對我來說,這聽起來像是做了非反動來源反動的一種方式,但隨後你來的例子,其中第一個是這樣的:

Tracker.autorun(function() { 
    var oldest = _.max(Monkeys.find().fetch(), function (monkey) { 
    return monkey.age; 
    }); 
    if (oldest) 
    Session.set("oldest", oldest.name); 
}); 

究竟是如何從這種不同不使用Tracker.autorun?遊標已經是一個反動的來源,並且使事情更加混亂下一個例子涉及另一個反動的來源:會話。

是否Tracker.autorun只適用於反動的來源,如果是的話,在Tracker內使用它們有什麼好處?讓他們加倍反動?

回答

33

爲了實施反應式編程(事件驅動的編程的一個變體),流星使用2個不同的概念:

  • 反應性計算:代碼段,將反應性地再次運行每個它們的底層依賴性修改時間。
  • 反應性數據源:能夠在反應計算中使用時註冊依賴性的對象使其無效並使其再次以新數據值運行。

這兩個概念由兩個很少使用底層Tracker對象,即Tracker.Computation和輔助對象Tracker.Dependency,其是用於存儲一組計算的容器來實現。

Tracker.Computation是具有2種重要的方法的對象:

  • invalidate(),這是造成計算重新運行。
  • onInvalidate(callback)用於實際運行計算任意代碼。

當你調用Tracker.autorun,你基本上是創建一個新的計算和註冊的onInvalidate回調跟你擦肩而過作爲參數的函數。

A Tracker.Dependency是具有2種方法的計算的集合。

  • depend():將當前計算添加到集合中。
  • changed():被調用時,使每個註冊的計算無效。

當反應性數據源寄存器的運算,它是調用Dependency.depend(),它簡單地將當前計算(如果有的話),以設定的追蹤計算的內部的相關性。

當被動數據源被修改時,它調用Dependency.changed(),這將使該集合中的每個已註冊計算無效。

來源:The Meteor Tracker manual

在流星框架中,通常只處理幾個實現反應式編程概念的高層次對象。

  • 反應式計算是使用Tracker.autorun衍生的,默認情況下模板助手總是在反應計算中運行。
  • 反應數據源通過使用Tracker.Dependency無效計算,它們包括MiniMongo光標,Session變量,Meteor.user(),等...

使用Tracker.autorun當你需要重新運行被動任意代碼模板助手之外,例如在模板onRendered生命週期事件中,使用快捷方式this.autorun(產生一個在模板被銷燬時自動停止的反應式計算)對任何反應性數據源修改做出反應。

這是一個模板的小例子,它可以計算單擊按鈕的次數,並在單擊10次時將計數器重置爲0。

HTML

<template name="counter"> 
    <div class="counter> 
    <button type="button">Click me !</button> 
    <p>You clicked the button {{count}} times.</p> 
    </div> 
</template> 

JS

Template.counter.onCreated(function(){ 
    this.count = new ReactiveVar(0); 
}); 

Template.counter.onRendered(function(){ 
    this.autorun(function(){ 
    var count = this.count.get(); 
    if(count == 10){ 
     this.count.set(0); 
    } 
    }.bind(this)); 
}); 

Template.counter.helpers({ 
    count: function(){ 
    return Template.instance().count.get(); 
    } 
}); 

Template.counter.events({ 
    "click button": function(event, template){ 
    var count = template.count.get(); 
    template.count.set(count + 1); 
    } 
}); 
+0

偉大的答案,它解決了我在onRendered那裏有另外一個問題,在Tracker.autorun,我不能使用get訪問模板this.find( '...')。通過使用this.autorun和.bind(this),我能夠使事情發揮作用。問題是.bind(this)需要做一個this.find('')?它的目的是什麼? – Aaron

+1

那麼,這將是另一個問題,看看:http://javascriptissexy.com/javascript-apply-call-and-bind-methods-are-essential-for-javascript-professionals/ Meteor 1.2將介紹ES2015的支持和Arrow功能,使得綁定無關緊要。 https://github.com/lukehoban/es6features#arrows – saimeunt

相關問題