<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                --- title: 高級的響應性 slug: advanced-reactivity date: 0011/01/02 number: 11.5 points: 10 sidebar: true photoUrl: http://www.flickr.com/photos/ikewinski/8676146109/ photoAuthor: Mike Lewinski contents: 學習如何在 Meteor 建立響應數據源。|建立一個簡單的響應式數據源例子。|看 Tracker 和 AngularJS 的對比。 paragraphs: 29 --- 雖然需要你自己寫代碼來跟蹤依賴變量的情況十分罕見,了解依賴變量的工作流程還是十分必要的。 設想我們現在需要跟蹤一下 Microscope上,當前用戶的 Facebook 朋友在 “like” 某一篇帖子的數量。 讓我們假設我們已經解決了 Facebook 用戶認證的問題,運用了正確的 API 調用,而且也解析了相關數據。 我們現在有一個異步的客戶端函數返回 like 的數量,`getFacebookLikeCount(user, url, callback)`。 需要特別強調的是要記住這個函數是十分 *非響應式* 而且非實時的。它發起一個 HTTP 請求到 Facebook, 得到一些數據, 然后作為回調函數參數返回給我們的應用程序。 但是如果 like 數改變了而這個函數不會重新運行,那么我們的界面上就無法得到當前最新數據了。 要解決這個問題,我們首先使用 `setInterval` 來每隔幾秒鐘調用一次這個函數: ~~~js currentLikeCount = 0; Meteor.setInterval(function() { var postId; if (Meteor.user() && postId = Session.get('currentPostId')) { getFacebookLikeCount(Meteor.user(), Posts.find(postId).url, function(err, count) { if (!err) { currentLikeCount = count; } }); } }, 5 * 1000); ~~~ 任何時候當我們檢查 `currentLikeCount` 變量, 我們期望可以得到一個5秒鐘之內準確的數據。我們現在在幫助方法使用這個變量。代碼如下: ~~~js Template.postItem.likeCount = function() { return currentLikeCount; } ~~~ 然而,我們無法每次當`currentLikeCount` 改變的時候重繪模板。盡管變量自己現在可以偽實時了,但是它不是*響應式的*所以無法正確地和 Meteor 生態環境中的其他部分進行溝通。 ### Tracking Reactivity: Computations Meteor 的響應性是靠 *依賴* 來控制的, 就是一個跟蹤 Computation 的數據結構。 正如我們此前在響應式章節看到的, 一個 computation 是一段代碼用來處理響應式數據。我們的例子中有一個 computation 隱式的建立給 `postItem` 這個模板用。 這個模板中的每個幫助方法都有自己的 computation 。 你可以想象這個 computation 就是一段專門關注響應式數據的代碼。 當數據改變了, 這個 computation 就會通知 (通過 `invalidate()`) , 而且也正是 computation 來決定是否有什么工作需要做。 ### 將變量變為響應式函數 將變量 `currentLikeCount` 放到一個響應式數據源中,我們需要跟蹤所有依賴這個變量的 computations.這需要把它從變量變為一個函數 (有返回值的函數): ~~~js var _currentLikeCount = 0; var _currentLikeCountListeners = new Tracker.Dependency(); currentLikeCount = function() { _currentLikeCountListeners.depend(); return _currentLikeCount; } Meteor.setInterval(function() { var postId; if (Meteor.user() && postId = Session.get('currentPostId')) { getFacebookLikeCount(Meteor.user(), Posts.find(postId), function(err, count) { if (!err && count !== _currentLikeCount) { _currentLikeCount = count; _currentLikeCountListeners.changed(); } }); } }, 5 * 1000); ~~~ <%= highlight "1~7,14~17" %> 我們建立了一個叫 `_currentLikeCountListeners` 的依賴,它來跟蹤所有用到 `currentLikeCount()` 的 computations. 當 `_currentLikeCount` 值發生變化,我們通過調用依賴的 `changed()` 函數,來通知所有 computations 數據變化了。 這些 computations 可以繼續處理下面的數據變化。 你可能覺得這像是在響應式數據源上的很多引用,你說對了,Meteor 提供很多工具使這項工作簡單 (你不需要直接調用 computations , 他們會自動運行)。有一個叫做 `reactive-var` 的包,它的內容正是函數 `currentLikeCount()` 要做的事。我們加入這個包: ~~~bash meteor add reactive-var ~~~ 使用它可使我們的代碼簡化一點: ~~~js var currentLikeCount = new ReactiveVar(); Meteor.setInterval(function() { var postId; if (Meteor.user() && postId = Session.get('currentPostId')) { getFacebookLikeCount(Meteor.user(), Posts.find(postId), function(err, count) { if (!err) { currentLikeCount.set(count); } }); } }, 5 * 1000); ~~~ <%= highlight "1,9" %> 現在使用這個包,我們在幫助方法中調用 `currentLikeCount.get()`,它會像之前一樣工作。有另外一個有用的包 `reactive-dict`, 它提供 key-value 存儲 (像 `Session` 一樣)。 ### Comparing Tracker to Angular [Angular](http://angularjs.org/) 是一個客戶端響應式庫,是 Google 的家伙們開發的。我們來比較 Meteor 和 Angular 的依賴跟蹤方式。他們的實現方式非常不同。 我們已經知道 Meteor 使用一些被稱為 comptations 的代碼來實現依賴跟蹤的。這些 computations 被特殊的 "響應式" 數據源(函數)跟蹤,在數據變化的時候將他們自己標記為 invalidate。當需要調用 `invalidate()` 函數時,響應式數據源_顯式的_通知所有依賴。請注意這是數據變化時的一般情況,數據源也可以因為其他原因觸發 invalidation。 另外,盡管通常情況下當數據 invalidate 時 computations 只是重新運行,但是你也可以在此時指定任何你想要的行為。這些給了用戶很高的響應式控制權。 在 Angular 中,響應式是通過 `scope` 對象來調節的。一個 scope 可以看做是擁有一些特殊方法的普通 js 對象。 當你的響應式數據依賴于 scope 中的一個值,你調用 `scope.$watch` 方法,告訴 expression 你關心的數據(例如: 你關心 scope 中的哪些數據)和一個當 expression 發生變化時每次都運行的監聽器。因此你需要顯示的提供當 expression 數據變化時你要做的操作。 回到之前 Facebook 的例子,我們的代碼可以寫成如下: ~~~js $rootScope.$watch('currentLikeCount', function(likeCount) { console.log('Current like count is ' + likeCount); }); ~~~ 當然,就像在 Meteor 中你很少需要去建立 computations, 在 Angular 中你無須經常顯示調用 `$watch`, `ng-model` 和 `{{expressions}}` 會自動建立跟蹤,之后當數據變化時他們會處理重新展示的事情。 當響應式數據發生變化時, `scope.$apply()` 方法會被調用。他會重新計算 scope 中所有的 watcher, 然后只調用 expression 值發生變化的 watcher 的監聽器方法。 因此 `scope.$apply()` 方法和 Meteor 中的 `dependency.changed()` 很相似,除了它是在 scope 級別操作,而不是給你控制權決定哪個 listener 需要重新 evaluate。換句話說,較少的控制使得 Angular 可以通過聰明和高效的方式來決定哪些 listener 需要重新 evaluate。 在 Angular 中,我們的 `getFacebookLikeCount()` 函數看起來如下: ~~~js Meteor.setInterval(function() { getFacebookLikeCount(Meteor.user(), Posts.find(postId), function(err, count) { if (!err) { $rootScope.currentLikeCount = count; $rootScope.$apply(); } }); }, 5 * 1000); ~~~ <%= highlight "5~6" %> 必須承認,Meteor 替我們完成了響應式的大部分繁重工作,但是希望,通過這些模式的學習,可以對你的深入研究起到幫助。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看