【问题标题】:Meteor collection insert not updating on client流星收集插入未在客户端更新
【发布时间】:2015-02-06 20:36:48
【问题描述】:

我目前遇到了 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 });
  });

日志

如果我使用流星在 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

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

【问题讨论】:

  • 我将您的代码放入meteorpad.com 并且添加的每个项目的网页更新而不刷新。您的浏览器的开发控制台中是否出现任何错误?也许是其他原因导致您的错误。

标签: javascript mongodb meteor


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

    您的出版物:

    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");

    如果您使用的是铁:路由器。在路由中,您可以像这样直接定义您的助手和订阅,然后在模板中调用 {{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})
                  };
                }           
            }
        }
        });
    

    永远记住,当您出版杂志时,您需要一个订阅者流程。收藏也是如此。

    干杯,

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-11-25
        • 2013-03-18
        • 2014-09-13
        • 2015-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多