1

我有进行插入的流星方法。我使用 Regulate.js 进行表单验证。

我将 game_id 字段设置为 Meteor.uuid() 以创建一个唯一值,我还使用 Iron 路由器将其路由到 /game_show/:game_id。

如您所见,我正在记录游戏的详细信息,这很好用。(图片链接到下面的日志)

文件:/lib/methods.js

Meteor.methods({
create_game_form : function(data){

    Regulate.create_game_form.validate(data, function (error, data) {
      if (error) {
        console.log('Server side validation failed.');
      } else {
        console.log('Server side validation passed!');
        // Save data to database or whatever...
        //console.log(data[0].value);
        var new_game = {
            game_id: Meteor.uuid(),
            name : data[0].value,
            game_type: data[1].value,
            creator_user_id: Meteor.userId(),
            user_name: Meteor.user().profile.name,
            created: new Date()
        };
        console.log("NEW GAME BEFORE INSERT:  ", new_game);
        GamesData.insert(new_game, function(error, new_id){

            console.log("GAMES NEW MONGO ID: ", new_id)
            var game_data = GamesData.findOne({_id: new_id});

            console.log('NEW GAME AFTER INSERT:  ', game_data);
            Session.set('CURRENT_GAME', game_data);

        });
      }
    });         
  }
 });

此时从 console.log 出来的所有数据都可以正常工作

在此方法调用客户端路由到 /game_show/:game_id

Meteor.call('create_game_form', data, function(error){  
    if(error){
        return alert(error.reason);
    }
    //console.log("post insert data for routing variable " ,data);

    var created_game = Session.get('CURRENT_GAME');

    console.log("Session Game ", created_game);
    Router.go('game_show',  {game_id: created_game.game_id});

});

在这个视图中,我尝试使用刚刚插入的 game_id 加载文档

Template.game_start.helpers({
game_info: function(){      
    console.log(this.game_id);
    var game_data = GamesData.find({game_id: this.game_id});
    console.log("trying to load via UUID ", game_data);
    return game_data;
}
});

抱歉不能上传图片... :-(

https://www.evernote.com/shard/s21/sh/c07e8047-de93-4d08-9dc7-dae51668bdec/a8baf89a09e55f8902549e79f136fd45

正如您从下面的控制台日志图像中看到的那样,一切都匹配

  • 插入前记录的 id
  • 使用 findOne() 在插入回调中记录的 id
  • 在 url 中传递的 id

但是,我插入的 mongo ID 和 UUID 不存在,其中唯一的文档具有除这两个之外的所有其他字段匹配!

不知道我做错了什么。谢谢!

4

1 回答 1

2

问题是您的代码在客户端运行(或者至少看起来像从屏幕截图中看到的那样)。

在流星中,Meteor.methods在客户端运行的是模拟存根。这意味着您将创建“假”数据的东西放在那里,这样您就可以避免用户感到延迟。这是因为服务器需要 1-4 秒才能回复实际插入数据库的内容。不过,这并不是真正的问题。

这给您带来麻烦的原因是该方法运行了两次(一次在服务器上,一次在客户端上),因此它会生成两个不同Meteor.uuid的 s,因为它们是随机的。所以这就是为什么你有不一致的地方。您看到的是最初的“假”,然后服务器发送真实的。

这就是 Meteor 如何使它看起来像是立即插入了数据,即使它还没有完全插入。

要解决此问题,请摆脱.method您在客户端上的所有内容,以便您只有一个在服务器上运行。您需要game_id从服务器而不是从客户端获取。

如果您想保留延迟补偿,请像处理其他表单数据一样传入Meteor.uuiddata这样game_id,服务器和客户端都将保持一致。

于 2013-11-05T21:59:19.450 回答