流星集合插入不在客户端更新

时间:2014-12-09 02:51:43

标签: javascript mongodb meteor

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

以下是插入位于'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'

的项目的服务器发布
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'

的方法的代码
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'的模板中

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

我刚开始学习Meteor。我感谢任何帮助!

修改

感谢您的回复,

我已尝试过这些建议并仍然得到相同的结果。我尝试过将用户与家庭联系起来的不同方式,但仍然存在同样的问题。我可以从客户端插入一个项目,它存在于服务器端,但它在客户端不存在。我敢肯定我在这里缺少一些小东西,但对于我的生活,却找不到它。

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

客户特定代码

位于'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'

的我的馆藏的代码
//Sub to our collections
Meteor.subscribe('households');
Meteor.subscribe('items');

代码迭代显示位于'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 = 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 = 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'

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在localhost上启动该站点。页面出现时(没有用户登录),这是服务器控制台输出:

=> 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包)。这是该点的输出。

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表单创建一个家庭。此时服务器上没有新输出,但这是客户端的输出:

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表单添加一个项目。任务显示在屏幕上闪烁然后消失。这是此时的服务器输出:

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

此时是客户端输出:

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

此时项目存在于服务器数据库中,但如果我使用chrome中的Web控制台,则执行命令Items.findOne();它返回undefined。

3 个答案:

答案 0 :(得分:0)

可能会有更多内容,但我无法看到您在客户端包含Meteor.subscribe("items")的位置,因为这会将记录从服务器上的发布传递到客户端

同样在您的发布中,您可以使用

if (this.userId) {
    //do stuff logged in
} else {
    this.stop();
}

而不是选择用户ID的Meteor.user()记录来检测客户端是否已登录。

答案 1 :(得分:0)

您的出版物:

Meteor.publish("items", function(){
  if(user = Meteor.user()){
    return Items.find( {household : user.household});
  }
  else{
    this.ready();
  }
});

你的帮手:

Template.itemList.helpers({
  items: function() {
    return Items.find({}, {sort : {checked: 1, createdAt: -1}});
  }
});

您的订阅(客户端):     Meteor.subscribe( “项目”);

如果你正在使用铁:路由器。在路线中,您可以直接定义您的助手和您的订阅,只需在模板中调用{{items}}:

    Router.route('myRoute', function(){
        this.render('myRouteTemplate');
    }, {
    path: '/myRoutePath',
    waitOn: function(){
        if(user = Meteor.user()) {
            var subscriptions = [];
            //
            // Subscribe to your subscription
            //===============================
            subscriptions.push(Meteor.subscribe('items'));

            return subscriptions;
        }
    },
    data: function(){
        var context;
        if(this.ready()) {
            if (user = Meteor.user()) {
            context = {
                items: Items.find( {household : user.household})
              };
            }           
        }
    }
    });

永远记住,当您发布杂志时,您需要一个订阅者流程。收藏也是一样。

干杯,

答案 2 :(得分:0)

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