如何正确使用Meteor.setInterval()和Collection.update()

时间:2016-09-29 15:55:22

标签: javascript mongodb meteor

你好,对不起我的英语。

我有一个方法“updateCounterState”,用于在我的mongodb-Collection中每秒递增和更新一个数字,并在我的html文件中的模板中显示这个数字。它似乎工作,但我每次使用此功能时都会得到两个错误。三天,我试图弄清楚如何解决这些错误。我相信由于我的异步更新,我必须将此代码块与Meteor.bindEnvironment-Wrapper一起使用。但是,我不知道如何使用它来修复这些错误。或许我完全错了,这些错误还有其他原因。

编辑#2:

的客户机/ main.html中

<head>
  <title>test-timer</title>
</head>

<body>
  {{> timeTrackerTemplate}}
</body>

<template name="timeTrackerTemplate">
  {{#each showCounterState}}
    <p class="counter-state">{{state}}</p>
    <button class="start-counting">Start</button>
  {{/each}}
</template>

的客户机/ main.js

import { Template } from 'meteor/templating';

Template.timeTrackerTemplate.events({
    'click .start-counting': function(e) {
         Meteor.call('updateCounterState', this._id);
    }
});

服务器/ main.js

import { Meteor } from 'meteor/meteor';

Meteor.startup(() => {
  // code to run on server at startup
});

methods.js(根文件夹)

Meteor.methods({
    'updateCounterState': function(id) {
        Meteor.setInterval(function() {
            TimeTracker.update(
                {_id: id},
                {
                    $inc: {state: 1},
                },
            );
        }, 1000);
    }
});

ttcollection.js(根文件夹)

TimeTracker = new Mongo.Collection('testtracker');

if (Meteor.isClient) {
    Template.timeTrackerTemplate.helpers({
        showCounterState: function () {
            return TimeTracker.find();
        }
    });
}

流星:PRIMARY&GT; db.testtracker.find({})

{ "_id" : ObjectId("57ee677227a0af6b59dc12ce"), "state" : 147 }
{ "_id" : ObjectId("57ee677a27a0af6b59dc12cf"), "state" : 148 }
{ "_id" : ObjectId("57ee6e6027a0af6b59dc12d0"), "state" : 73 } 
每次按下按钮时

错误:

Exception while simulating the effect of invoking 'updateCounterState' Error: Can't set timers inside simulations
    at withoutInvocation (http://localhost:3000/packages/meteor.js?hash=ae8b8affa9680bf9720bd8f7fa112f13a62f71c3:463:13)
    at bindAndCatch (http://localhost:3000/packages/meteor.js?hash=ae8b8affa9680bf9720bd8f7fa112f13a62f71c3:471:33)
    at Object.setInterval (http://localhost:3000/packages/meteor.js?hash=ae8b8affa9680bf9720bd8f7fa112f13a62f71c3:498:24)
    at updateCounterState (http://localhost:3000/app/app.js?hash=f641538433c68c8f8b820f0e05cebb12531cb357:66:20)
    at http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:3973:25
    at withValue (http://localhost:3000/packages/meteor.js?hash=ae8b8affa9680bf9720bd8f7fa112f13a62f71c3:1077:17)
    at Connection.apply (http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:3964:54)
    at Connection.call (http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:3840:17)
    at Object.clickStartCounting (http://localhost:3000/app/app.js?hash=f641538433c68c8f8b820f0e05cebb12531cb357:47:20)
    at http://localhost:3000/packages/blaze.js?hash=a9372ce320c26570a2e4ec2588d1a6aea57de9c1:3718:20 Error: Can't set timers inside simulations
    at withoutInvocation (http://localhost:3000/packages/meteor.js?hash=ae8b8affa9680bf9720bd8f7fa112f13a62f71c3:463:13)
    at bindAndCatch (http://localhost:3000/packages/meteor.js?hash=ae8b8affa9680bf9720bd8f7fa112f13a62f71c3:471:33)
    at Object.setInterval (http://localhost:3000/packages/meteor.js?hash=ae8b8affa9680bf9720bd8f7fa112f13a62f71c3:498:24)
    at updateCounterState (http://localhost:3000/app/app.js?hash=f641538433c68c8f8b820f0e05cebb12531cb357:66:20)
    at http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:3973:25
    at withValue (http://localhost:3000/packages/meteor.js?hash=ae8b8affa9680bf9720bd8f7fa112f13a62f71c3:1077:17)
    at Connection.apply (http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:3964:54)
    at Connection.call (http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:3840:17)
    at Object.clickStartCounting (http://localhost:3000/app/app.js?hash=f641538433c68c8f8b820f0e05cebb12531cb357:47:20)
    at http://localhost:3000/packages/blaze.js?hash=a9372ce320c26570a2e4ec2588d1a6aea57de9c1:3718:20

2 个答案:

答案 0 :(得分:0)

updateCounterState函数定义在哪里?它是模板的帮手吗? TimeTracker集合中的允许/拒绝状态是什么?

编辑(问题更新后)

首先,您的方法将TimeTracker的ID作为单个参数,但是当您调用方法时,您不会传递任何内容。你应该从客户端创建一个TimeTracker对象然后传递它的_id,或者在你的函数中不带参数并在服务器上创建它(在这种情况下,你的方法应该返回_id来保持跟踪它。

然后,将代码放在根文件夹中不是最佳做法,您应该使用/imports文件夹然后使用import { foo } from 'foo.js',或将代码放在/server或{{1}中}。

你的模板助手返回一个没用的Mongo游标。如果要返回单个TimeTracker,请使用/client返回对象。基本上,你应该有类似的东西:

TimeTracker.findOne({ _id: id })

答案 1 :(得分:0)

我解决了我的错误。重要的是只在服务器端调用带有集合的方法 - 特别是没有&#34;不安全&#34;封装

if (Meteor.isServer) {
  //Meteor.methods()
}