流星集合插入未在客户端更新 [英] Meteor collection insert not updating on client

查看:41
本文介绍了流星集合插入未在客户端更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前在 Meteor 中遇到集合插入问题.我调用一个方法将一个新项目插入到一个集合中.服务器数据库显示新项目,但客户端没有该集合的记录.我发现如果我刷新页面,引用集合的模板会填充并起作用.

I'm currently having an issue with a collection insert in Meteor. I call a method to insert a new item into a collection. The server database shows the new item but the client side has no record of the collection. I've found if I refresh the page, my template referencing the collection populates and works.

这是插入位于'lib/collections/items.js'的项目的方法

Here is the method inserting the item located at 'lib/collections/items.js'

Items = new Mongo.Collection("items");

Meteor.methods({
  addItem: function (text) {
    if (! Meteor.userId()){
      throw new Meteor.Error("not-authorized");
    }
    console.log(text);
    console.log(Meteor.userId());
    console.log(Meteor.user().username);
    console.log(Meteor.user().household);
    Items.insert({
      text: text,
      createdAt: new Date(), //current time
      owner: Meteor.userId(),
      username: Meteor.user().username,
      household: Meteor.user().household
    });
  },

这是位于'/server/main.js'的项目的服务器发布

Here is the server publishing of the items located at '/server/main.js'

Meteor.publish("items", function(){
  if(typeof Meteor.users.findOne({'_id': this.userId}) === 'undefined') return null;
    return Items.find( {household : Meteor.users.findOne({'_id': this.userId}).household});
}); 

这是调用位于'client/main.js'的方法的代码

Here is the code calling the method located at 'client/main.js'

Template.body.events({
  "submit .new-task": function (event) {
    // This function is called when the new task form is submitted

    var text = event.target.text.value;
    text = text.trim();
    if(text)//Check for non-null, non-empty
      {
        text = capitalizeEachWord(text);
        console.log(text);
        Meteor.call("addItem",text);
      }

      //Clear form
      event.target.text.value = "";

      //Prevent default form submit
      return false;
    },

此处是查询集合以显示在client/templates/itemList.js"的模板中的位置

Here is where the collection is queried from to display in a template at 'client/templates/itemList.js'

Template.itemList.helpers({
  items: function() {
    console.log('Trying to subscribe');
    return Items.find({}, {sort : {checked: 1, createdAt: -1}});
  }

我刚刚开始学习 Meteor.感谢您的帮助!

I'm just starting to learn Meteor. I appreciate any help!

编辑

感谢您的回复,

我已经尝试了这些建议,但仍然得到相同的结果.我现在尝试了一种不同的方式来将用户与家庭联系起来,但仍然遇到相同的问题.我可以从客户端插入一个项目,它存在于服务器端,但它不存在于客户端.我确定我在这里遗漏了一些小东西,但对于我的生活,找不到它.

I've tried these suggestions and still getting the same result. I've tried a different way of relating users to households now and still having the same issues. I can insert an item from the client, it exist on the server side, and yet it doesn't exist on the client side. I'm sure i'm missing something small here but for the life of me, can't find it.

我知道这是一个巨大的信息转储,但这里是我更新的源代码(仍然产生同样的问题)和日志.我试图把我所知道的关于这个问题的一切都放在一边.谢谢你的帮助!我刚刚开始使用 Meteor,我不知道有谁开发过它,所以现在进行故障排除有点困难.

I know this is a huge dump of info but here is my updated source code (still producing the same problem) and logs. I've tried to put everything I know about this issue. Thanks for any help! I'm just starting out with Meteor and I know no one who develops in it so troubleshooting is a bit tough right now.

客户特定代码

位于'client/main.js'

Located at 'client/main.js'

Template.body.helpers({
  householdId: function() {
    //return Meteor.users.findOne({'_id': Meteor.userId()}).household;
    if(Meteor.userId() &&
      Households.findOne({users : {$regex : new RegExp(Meteor.userId())}}))
    {      
      console.log('Trying to get id');
      return Households.findOne({users : {$regex : new RegExp(Meteor.userId())}})._id;
    }
  }
});
Template.body.events({
  "submit .new-task": function (event) {
    // This function is called when the new task form is submitted

    var text = event.target.text.value;
    text = text.trim();
    if(text)//Check for non-null, non-empty
      {
        text = capitalizeEachWord(text);
        console.log(text);
        Meteor.call("addItem",text);
      }

      //Clear form
      event.target.text.value = "";

      //Prevent default form submit
      return false;
    },
    "submit .new-household": function (event) {
      // This function is called when the new task form is submitted
      var insertedId;

      var text = event.target.householdName.value;
      text = text.trim();
      if(text)//Check for non-null, non-empty
        {
          text = capitalizeEachWord(text);
          Meteor.call("createHousehold", text);
        }


        //Prevent default form submit
        return false;
      }
  });


Accounts.ui.config({
  passwordSignupFields: "USERNAME_ONLY",
});

用于订阅位于client/application.js"的我的集合的代码

Code to subscribe to my collections located at 'client/application.js'

//Sub to our collections
Meteor.subscribe('households');
Meteor.subscribe('items');

代码遍历项目以显示位于'client/templates/itemList.js'

Code iterating through the items to display located at 'client/templates/itemList.js'

Template.itemList.helpers({
  items: function() {
    console.log('Trying to subscribe');
    return Items.find(
      {
        household : Households.findOne( {users : {$regex : new RegExp(this.userId)}})._id
      }
    , {sort : {checked: 1, createdAt: -1}});
  },
  householdId: function() {
    //return Meteor.users.findOne({'_id': Meteor.userId()}).household;
    if(Meteor.userId())
    {      
      console.log('Trying to get id from ');
      return Households.findOne({users : {$regex : new RegExp(Meteor.userId())}})._id;
    }
  }
});

集合代码

家庭收藏代码位于'lib/collections/households.js'

Households collection code located at 'lib/collections/households.js'

Households = new Mongo.Collection("households");

Meteor.methods({
  createHousehold: function(text) {
    var insertedId;
    insertedId = Households.insert({
      householdName: text,
      createdAt: new Date(), //current time
      users: this.userId
    });
  }//Add user in the future
});

项目集合代码位于'lib/collections/items.js'

Items Collection code located at 'lib/collections/items.js'

Items = new Mongo.Collection("items");

Meteor.methods({
  addItem: function (text) {
    if (! Meteor.userId()){
      throw new Meteor.Error("not-authorized");
    }
    console.log('Inserting item')
    console.log('Item : ' + text);
    console.log('UserId : ' + Meteor.userId());
    console.log('Username : ' + Meteor.user().username);
    console.log('Household : ' + Households.findOne( {users : {$regex : new RegExp(Meteor.userId())}})._id);
    Items.insert({
      text: text,
      createdAt: new Date(), //current time
      owner: Meteor.userId(),
      username: Meteor.user().username,
      household: Households.findOne( {users : {$regex : new RegExp(Meteor.userId())}})._id
    });
    return true;
  },
  deleteItem: function (itemId) {
    Items.remove(itemId);
  },
  setChecked: function(itemId, setChecked) {
    Items.update(itemId, { $set: {checked: setChecked}});
  }
});

服务器代码

服务器代码位于'server/main.js'

The server code is located at 'server/main.js'

Meteor.publish("households", function(){
  console.log('Trying to subscribe');
  console.log(this.userId);
  if(this.userId)
  {
    //var query = { users : new RegExp("/"+this.userId+"/")};
    //console.log(Households.findOne( query ));
    console.log(Households.findOne( {users : {$regex : new RegExp(this.userId)}}));
    return Households.find( {users : {$regex : new RegExp(this.userId)}});
  }
  else
  {
    console.log('Too early');
    return null;
  }
});



Meteor.publish("items", function(){
  console.log('Trying to get items');
  if(!this.userId ||
    !Households.findOne( {users : {$regex : new RegExp(this.userId)}}))
    {
      console.log('Returning null');
      return null;
    }
    console.log(Items.findOne( {household : Households.findOne( {users : {$regex : new RegExp(this.userId)}}) }));
    console.log(this.userId);
    return Items.find( {household : Households.findOne( {users : {$regex : new RegExp(this.userId)}})._id });
  });

日志

如果我使用meteor 在本地主机上启动站点.当页面出现时(没有用户登录),这是服务器控制台输出:

If I start the site on localhost using meteor. When the page comes up (no user logged in), this the server console output:

=> App running at: http://localhost:3000/
I20141209-10:26:50.719(-5)? Trying to subscribe
I20141209-10:26:50.766(-5)? null
I20141209-10:26:50.766(-5)? Too early
I20141209-10:26:50.766(-5)? Trying to get items
I20141209-10:26:50.767(-5)? Returning null

接下来我成功创建了一个用户帐户(使用 accounts-ui/accounts-password 包).这是该点的输出.

Next I successfully create a user account (using accounts-ui/accounts-password packages). This is the output to that point.

I20141209-10:31:59.562(-5)? Trying to subscribe
I20141209-10:31:59.565(-5)? null
I20141209-10:31:59.566(-5)? Too early
I20141209-10:31:59.566(-5)? Trying to get items
I20141209-10:31:59.566(-5)? Returning null
I20141209-10:32:16.145(-5)? Trying to subscribe
I20141209-10:32:16.145(-5)? 8Skhof4jL2pSguT8Q
I20141209-10:32:16.146(-5)? undefined
I20141209-10:32:16.147(-5)? Trying to get items
I20141209-10:32:16.148(-5)? Returning null

接下来,我使用 .new-household 表单创建一个家庭.此时服务器上没有新的输出,但这是客户端的输出:

Next I create a household using the .new-household form. No new output on the server at this point but here is the output on the client side:

main.js?ba2ac06f3ff7f471a7fa97093ac9ed5c01e0c8cd:7 Trying to get id
main.js?ba2ac06f3ff7f471a7fa97093ac9ed5c01e0c8cd:7 Trying to get id
itemList.js?a224bda493b90eb94bff9b88b48bb22eaa8aefe1:3 Trying to subscribe
main.js?ba2ac06f3ff7f471a7fa97093ac9ed5c01e0c8cd:7 Trying to get id
main.js?ba2ac06f3ff7f471a7fa97093ac9ed5c01e0c8cd:7 Trying to get id
itemList.js?a224bda493b90eb94bff9b88b48bb22eaa8aefe1:3 Trying to subscribe

此时我使用 .new-task 表单添加一个项目.任务在屏幕上闪烁显示,然后消失.这是此时的服务器输出:

At this point I add an item using the .new-task form. The task displays for a blink on screen then disappears. Here is the server output at this point:

I20141209-10:37:09.171(-5)? Inserting item
I20141209-10:37:09.172(-5)? Item : Beans
I20141209-10:37:09.172(-5)? UserId : 8Skhof4jL2pSguT8Q
I20141209-10:37:09.172(-5)? Username : pedro
I20141209-10:37:09.173(-5)? Household : M5NckT6ndqhRKCeWo

这是此时的客户端输出:

Here is the client output at this point:

main.js?ba2ac06f3ff7f471a7fa97093ac9ed5c01e0c8cd:21 Beans
items.js?2ca606d1e71e2e55d91421d37f060bd5d8db98fe:8 Inserting item
items.js?2ca606d1e71e2e55d91421d37f060bd5d8db98fe:9 Item : Beans
items.js?2ca606d1e71e2e55d91421d37f060bd5d8db98fe:10 UserId : 8Skhof4jL2pSguT8Q
items.js?2ca606d1e71e2e55d91421d37f060bd5d8db98fe:11 Username : pedro
items.js?2ca606d1e71e2e55d91421d37f060bd5d8db98fe:12 Household : M5NckT6ndqhRKCeWo

此时 Item 存在于服务器数据库中,但如果我使用 chrome 中的 web 控制台,执行命令 Items.findOne();它返回未定义.

At this point the Item exists within the server database, but if I, using the web console in chrome, execute the command Items.findOne(); it returns undefined.

推荐答案

我最终通过在我的应用程序中实现 Iron Router 并在呈现模板之前等待订阅准备好来解决这个问题.我相信我之前的问题是某种竞赛条件,但我对它的具体情况并不乐观.无论哪种方式,我都对我的解决方案感到满意,因为它解决了我的问题,并且我认为更好、更容易理解地构建了我的网站流程.

I ended up fixing this issue by implementing Iron Router in my application and waiting on subscriptions to be ready before rendering a template. I believe that my issue before was some kind of race condition but i'm not positive on the specifics of it. Either way i'm satisfied with my solution because it fixes my issue and structures the flow of my site better and more understandably I think.

这篇关于流星集合插入未在客户端更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆