2014-11-02 88 views
3

在允許客戶端實時聊天的應用程序中,我的目標是集成允許定義未來時間點消息的功能。取決於流星當前時間的反應性訂閱

在以下示例中,我可以插入直接插入模板中的消息。但是,我只想顯示時間小於或等於當前時間的消息,但只要達到時間,就會自動顯示具有未來時間點的消息。例如,如果我通過調用Meteor.call("createMessage", 30000, "hello in 30 seconds")從控制檯插入消息(將來30秒後應顯示該消息),則消息應在30秒後自動顯示。

我開始將發佈功能中的查詢限制爲time: {'$lt': new Date()}。但是,我在製作這種反應時遇到了麻煩。我沒有成功嘗試Tracker.autoruncursor.observe的幾種組合。

任何人都可以給我一個提示,我如何在下面的運行示例中實現所需的反應性?

1)HTML文件

<body> 
    {{> chat}} 
</body> 

<template name="chat"> 
{{#each chatMessages}} 
    {{time}} - {{message}} <br> 
{{/each}} 
</template> 

2)js文件

//server and client 
Messages = new Mongo.Collection("messages"); //{time: Sun Nov 02 2014 22:17:32 GMT+0100 (CET), message: "hello"} 

//server 
if(Meteor.isServer){ 
    Meteor.methods({ 
    'createMessage': function(timeOffset, message){ 
     Messages.insert({ 
     time: new Date(new Date().getTime() + timeOffset), 
     message: message 
     }); 
    } 
    }); 

    Meteor.publish("messages", function(){ 
    return Messages.find({ 
     //time: {'$lt': new Date()} 
    }); 
    }); 
} 

//client 
if (Meteor.isClient) { 
    Template.chat.helpers({ 
    chatMessages: function(){ 
     return Messages.find({}); 
    } 
    }); 

    Tracker.autorun(function(){ 
    mySub = Meteor.subscribe('messages'); 
    }); 
} 

回答

1

如果日期()是一個反應數據源,它會工作,但事實並非如此。

您可以在服務器端創建一個定時器來處理它。我看到的最好的設計id:挑選下一個消息的未來日期,並設置一個具有時間差的Timer,並獲取下一個消息時間。當然,這取決於你的應用程序的工作方式。

瞭解更多關於定時器流星:https://docs.meteor.com/#/full/timers

+0

謝謝!因此,如果涉及date(),那麼查詢的結果不可能被反應?目前,我在Tracker.autorun的Messages集合上有一個計數器。這很好,但每當我的查詢涉及date()(例如只計算小於當前日期的文檔)時,它就不起作用。這是因爲如果我理解正確,date()本身沒有反應? – Miriam 2014-11-03 12:17:38

+1

是的。請記住,日期方法可能會損害您的服務器性能,我建議您找到更好的方法。如果你的消息非常接近,及時,彼此的結果是:一批數據庫查詢和定時器觸發。考慮在你的應用程序中做一些緩存。一些流星開發商不能停止思考被動,但有時添加標誌{reactive:false}在某些情況下沒有任何區別。如何獲取下一個50條消息以獲取緩存,以及何時獲取數據庫爲空? – 2014-11-03 12:43:33

1

反應意味着該視圖反映數據源用於製作該視圖,更新時,這些來源發生變化,然後才(作爲一個經驗法則)。因此,如果我們想要使用反應性來實現所描述的內容,那麼當消息上線時(輪廓模型沒有這種變化),我們必須引入反應性變化。

兩種方式做到這一點,我能想到的:

  • 的「將isLive」字段添加到消息,必須在正確的時間服務器更改它,使用定時回調和Meteor.startup(避免在重新啓動的情況下丟失消息)。有點複雜,但乾淨和高效(正確實施時)。
  • 在客戶端添加一個currentDate Session變量並使用Meteor.setInterval等,以保持當前所需(因爲會話變量是被動的)。

在第二個選擇中,用戶可以更改他們的系統時鐘或使用javascript控制檯訪問未來的消息。此外,設定時間間隔的反應事件看起來相當有意思,除非該時間間隔對問題域本身有意義(例如日曆應用程序更改用於繪製紅色圓圈的「今天」會話變量,每個午夜)。

更簡單(更好?)非反應性解決方案可能是簡單地將未來消息渲染爲隱藏元素,並使用JavaScript計時器在適當的時間顯示它們。但這一切都取決於你正在處理的內容。

+0

我正在和Meteor做一個遊戲,我可以在當前時間爲客戶端使用一個Session變量,並在一個「setInterval」函數中更新: 'Session.set(「REACTIVE_TIME_VAR」,new Date() )' 對於具有實時更新倒數定時器的事件或任何需要隨時間更新(而不僅僅是更新底層數據源)的事件而言,這非常方便。在我的特殊情況下,我只需要每秒更新一次,所以它不會讓客戶端性能顯着下降。最重要的是,它只需要我更改現有代碼的兩行。感謝這個建議! – Marty 2015-07-13 00:20:15