Meteor.js:如何定期从视图中查询收集文档

时间:2014-02-14 13:27:44

标签: javascript node.js meteor meteorite

我认为我希望基本上是一个动态幻灯片:

  1. 加载视图
  2. 启动一个计时器,以便每隔X秒返回一个特定集合中的随机文档(典型的collection.findOne()请求)
  3. 加载该项目时,触发附加数据的功能
  4. 这听起来像是一个典型的jquery _GET请求,但知道“流星”会很好。这样做的方式。

    这基本上是我想要做的出发点:

    // week_player.js
    
    
    var randomWeekInterval;
    
    // triggered when page is first loaded
    Template.weekPlayer.rendered = function(){
        console.log('rendered!');
        var tick = 0;
        randomWeekInterval = Meteor.setInterval(function(){
    
            console.log('week interval update ' + (tick++));
    
            var weekCount = Weeks.find().count();
            var randomWeekId = Math.floor(weekCount * Math.random());
    
            var randomWeek = Weeks.findOne(randomWeekId);
    
            // TODO: add some sort of listener for when the week is loaded
            // and trigger newDataHandler with the data
    
        }, 10 * 1000); // repeat every 10 seconds
    }
    
    // triggered when the new data is loaded
    Template.weekPlayer.newDataHandler = function(data){
        // got new data! here it is:
        console.log(data);
    }
    
    // triggered when leaving page: stop doing the interval
    Template.postPage.destroyed = function(){
        Meteor.clearInterval(randomWeekInterval);
    }
    

2 个答案:

答案 0 :(得分:2)

尝试这样的事情:

_.extend(Template.weekPlayer, {
  created: function() {
    this.randomWeekInterval = Meteor.setInterval(function() {
      Session.set("randomWeekIndex", Math.floor(Weeks.find().count() * Math.random()));
    }, 10 * 1000);
  },

  destroyed: function() {
    Meteor.clearInterval(this.randomWeekInterval);
  },

  week: function() {
    return Weeks.findOne({}, {
      skip: Session.get("randomWeekIndex"),
      transform: function(doc) {
        // Here's where you can manipulate the object after it is retrieved

        return doc;
      }
    });
  }
});

现在,您可以直接从模板中获取周对象,只要Session var发生更改,它就会自动更改为新周:

<template name="weekPlayer">
  {{#with week}}
    Start Date: {{startDate}} <br/>
    End Date: {{endDate}}
  {{/with}}
</template>

一些注意事项:

  • 间隔在created回调中设置,而不是rendered。这是为了确保每个setInterval始终只有一个clearInterval。如果它在rendered回调中,则每次渲染模板时都会设置一个新的间隔,这可能是数百次。您也会丢失对间隔对象的引用。

  • 因为我们在thiscreated回调中引用destroyed上的间隔,您可以拥有多个幻灯片,每个幻灯片都有自己的间隔对象。

    < / LI>
  • 我们使用Session来存储随机索引。每次运行Template.weekPlayer.week时,模板帮助程序函数Session.set("randomWeekIndex", "someValue")将自动重新运行。然后,模板将自动重新呈现,因为它取决于week帮助程序。

  • HTML部分假定您的week个对象包含startDateendDate个字段。它们当然可以遵循任何结构,transform选项允许您在显示它们之前修改它们的结构。如果对象状态良好,您可以从transform来电中删除findOne选项。

  • 我正在使用Underscore的_.extend来简洁。如果您之前没有看过,那就像说:

    Template.weekPlayer.created = function() { /* ... */ };
    Template.weekPlayer.destroyed = function() { /* ... */ };
    // ...
    

最后一点 - 你应该发现在使用Meteor时很少使用jQuery。每当你需要与Meteor服务器交谈时,你想使用Meteor方法而不是jQuery AJAX。每当您需要从服务器获取数据时,您都希望使用发布/订阅。无论何时你想进行基本的DOM操作,你都会让模板和反应式辅助函数(例如Template.weekPlayer.week)为你做,就像我在这里看到的那样。

答案 1 :(得分:0)

会话变量是被动的。您可以在weekPlayer模板上使用模板助手返回Session对象

模板助手

Template.weekPlayer.helpers({
    currentSlide: function(){
        return Session.get('currentSlide');
    }
});

<强>模板

<template name="weekPlayer">
    {{currentSlide}}
</template>

定期更新

var tick = 0;
Meteor.setInterval(function() {
    // update contents of slide data
    tick += 1;
    // set currentSlide Session object -- which triggers a redraw
    Session.set('currentSlide', tick);
}, 1000);

现在请注意,您可能需要执行 Meteor.setInterval 调用并将其移到 Template.weekPlayer.rendered 函数之外。这样你每次重绘时都不会创建一个新的Meteor.setInterval(或使用Meteor.clearInterval - 只是一些机制来阻止调用Session.set意外)