[英]Why isn't my meteor template being reactively rendered?
我有這樣的模板助手
Template.index.allUpcomingGames = function() {
return Games.find({date: {$gte: new Date()}}, {sort: {date: 1}});
};
因此,如果我沒看錯文檔,則每當查詢結果更改時,都應重新渲染模板。
我看到的實際行為是,當我第一次加載頁面(空的minimongo緩存)時,該模板未呈現任何結果。 當檢測到增量更改並且強制將模板重新呈現時,項目將以神奇的方式出現,因此大概是在查詢返回之前發生了初始頁面加載,並且隨后沒有像我期望的那樣進行被動重新呈現。 我究竟做錯了什么? 管理查詢模板依賴關系的最佳實踐是什么?
應該包括發布/訂閱。 很簡單,我只是在一分鍾發布所有內容,盡管一旦完成,它將變得更聰明。 我已經刪除了自動發布包。
發布
Meteor.publish("allGames", function(userId) {
return Games.find();
});
訂閱
Meteor.subscribe("allGames", this.userId);
如您所見,我還沒有使用userId
我已將其簡化為可復制的內容,看來我對收藏有一個基本的誤解。 我在這里整理了3個測試用例:
https://github.com/antiBaconMachine/meteorCollectionRenderingTests
我看到的3個測試的輸出是
我希望第一個測試能夠做出反應,因為forEach
應該獲取我認為是由車把{{#each}}
調用的文檔。從流星文檔中:
游標是一種反應性數據源。 當您第一次在反應式計算(例如,模板或自動運行)中使用fetch,map或forEach檢索游標的文檔時,Meteor將注冊對基礎數據的依賴性。
第二項測試按我預期的那樣工作,這使我感到困惑,因為唯一的區別是我檢索了計數。
我假設最后一個測試失敗了,因為我在准備好文檔並且一旦檢索到該查詢就不再是被動的來獲取這些文檔? 那只是一個猜測。
任何對此的見解將不勝感激,我有點迷茫。
注意:初始答案和之后的錯誤再現是完全不同的。 一個人幫助發現了另一個。 尋找該答案的第二部分以獲得真實信息。
回答最初的問題:
這種行為對我來說很有意義:
讓我們看看您的查詢:
Games.find({date: {$gte: new Date()}}, {sort: {date: 1}})
您正在尋找所有游戲,並按日期排序,該日期的日期大於 查詢 創建的日期。
因此,假設您在數據庫中有以下項目:
A, date: 100
B, date: 200
C, date: 300
您的客戶端js已加載,當前時間為350
。 您的查詢創建為Games.find({ date: {$gte: 350} }, {sort: {date: 1}});
。 當然,A,B和C落后於350
日期,因此不會呈現。
然后,將一個新游戲插入數據庫,例如D, date: 400
。 是的,它應該由查詢返回,該查詢查看在350
之后創建的所有內容。
您期望什么行為?
更新的補充:
這是一個錯誤。
該錯誤已提交給Shark渲染引擎。 新引擎(火花)已解決此問題,並將在下一個Meteor版本中發布。 (也許是0.7)
當您將minimongo游標作為模板數據上下文傳遞時,會發生該錯誤。 這是將數據獲取到模板的非常不尋常的方法。 我認為這就是為什么它存在這么長時間但未被發現的原因。
臨時解決方法是不將游標作為數據上下文傳遞。 相反,您可以傳遞id或name或其他任何名稱,然后為被調用方模板提供單獨的模板幫助程序,以返回適當的游標。
有趣的是:您無需將光標傳遞到模板,而是可以將其嵌入#with塊幫助器中,它將按預期工作:
{{#with games}}
<ul>
{{#if this.count}}
{{#each this}}
<li class="u-margin--sm">
<a href="/game/show/{{_id}}" class="col-md-8">{{name}}</a>
</li>
{{/each}}
{{else}}
<span class="t-small">No games</span>
{{/if}}
</ul>
{{/with}}
一切正常:)。
回復:withFetch
如果使用length
而不是count
它將按預期工作。 提取時,游標返回一個普通的JS數組,它沒有count
屬性,但是具有length
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.