【问题标题】:Meteor update collection error流星更新收集错误
【发布时间】:2015-10-30 16:26:58
【问题描述】:

我不知道我的代码有什么问题,我正在阅读 Discover Meteor 一书并构建了一个小应用程序来更好地学习这些概念:

Template.panelCM.events({
'click .editProductsCol': function(e) {
    e.preventDefault();
    if (confirm('Edit?')){

    var currentProduct = this._id;

    var productOptions = {
        name: $(e.target).find('[name=productName]').val(),
        description: $(e.target).find('[name=productDescription]').val()
    };

    Products.update(currentProduct, {$set: productOptions}, function(error) {
        if (error) {
            alert(error.reason);
            throwError('Error');
        } else {
            Router.go('tabPage');
        }
    });
}},

'click .deleteProductsCol': function(e) {
    e.preventDefault();

    if (confirm("Delete?")) {
        var currentProduct = this._id;
        Products.remove(currentProduct);
        Router.go('tabPage');
    }
}});

删除部分效果很好,只是我不知道哪里出了问题的更新.. 提交后它给了我这个错误: MongoError: '$set' is empty. You must specify a field like so: {$mod: {<field>: ...}}

这是我的模板:

<template name="panelCM">
{{#each products}}
    <div class="col-xs-12 col-sm-6 col-md-6 mainCol">
        <img src="../{{image}}"/>
        <input type="text" name="productName" id="productName" class="form-control" placeholder="{{name}}">
        <textarea name='productDescription' id="productDescription" class="form-control colP" rows="10"
                  placeholder="{{description}}" style="color: black"></textarea>
        <button type="submit" class="btn btn-lg btn-success form-control editProductsCol">Edit</button>
        <button type="submit" class="btn btn-lg btn-danger form-control deleteProductsCol">Delete</button>
    </div>
{{/each}}</template>

我做错了什么,我不太理解我认为的 productOptions var,如果我理解正确,我只是创建一个对象,该对象获取我放在该 html 元素上的任何内容,然后将其传递给我的 Products db 进行更新它,我不太明白的是,如果我还需要在模板上使用 id,我在 Discover Meteor 书中看到了它,但这没有意义,因为我找到了带有“名称”的正确元素(不知道那叫什么).. 另外,我在 productOptions 中使用的名称和描述应该与我在我的数据库中使用的名称和描述相同吧?

【问题讨论】:

  • 在控制台上运行$('[name=productName]').val()$('[name=productDescription]').val() 有什么收获?

标签: javascript mongodb meteor


【解决方案1】:

$.find 查找被调用的 DOM 元素的后代。您在没有子项的编辑按钮上调用它。这意味着它什么也没找到,并且对.val() 的调用返回undefined。 MongoDB 抱怨您将两个字段都设置为undefined,这几乎没有任何意义。试试这样的:

'click .editProductsCol': function(e, template) {
    e.preventDefault();
    if (confirm('Edit?')) {

    var productOptions = {
        name: template.$('[name=productName]').val(),
        description: template.$('[name=productDescription]').val()
    };

    Products.update(this._id, {$set: productOptions}, function(error) {
        if (error) {
            alert(error.reason);
            throwError('Error');
        } else {
            Router.go('tabPage');
        }
    });
  }
},

流星入门

让我们看一下代码。 Meteor 在事件处理程序中将this 绑定到您的模型,因此this._id(您分配给currentProduct 变量)获取您要更新的文档的ID。

所以,现在您要更新什么文档(MongoDB 项目称为文档)。如何做到这一点以及将其设置为什么?好吧,我们要根据表单数据进行更新。传递给事件处理程序的第二个参数是template 实例,它包含一个$ property,它只在模板的上下文中查询DOM。这就是我们获得表单值的地方。

现在,我们只需要在Meteor.collection 上调用update 方法,我们就成功了。正如您从文档中看到的,它将_id 作为选择器、修饰符对象和回调。您的修饰符是具有$set 属性的对象。它告诉 MongoDB 保持文档原样,只需添加/替换我们指示的字段(而不是替换整个文档)。

还有一点,如果没有特别的理由,我建议您将输入元素上的placeholder 属性替换为values。占位符只是一个视觉提示,它对表单内容本身没有任何意义。

    <input type="text" name="productName" id="productName" class="form-control" value="{{name}}" placeholder="Enter the name">
    <textarea name='productDescription' id="productDescription" class="form-control colP" rows="10" value="{{description}}" style="color: black" placeholder="Enter a description"></textarea>

【讨论】:

  • Holy.. 它有效,我现在明白为什么了,很好的答案!我确信它没有指向任何地方来更新它,但看不出代码有什么问题,因为在发现流星书上他们使用了类似的代码并且它工作正常..github.com/DiscoverMeteor/Microscope是的,你是对的价值在那里更有意义!谢谢你,真的!我收到的最佳答案!
  • 我怀疑这本书上的代码与表单上的submit 事件有关,不是吗?在这种情况下,e.target 是表单本身,find 按预期工作,因为输入元素是它的后代。无论哪种方式,您最好使用template.$ 方法,以确保您不会在模板之外搞砸任何东西。
  • 是的!从现在开始我将只使用 template.$,obrigado! :)
  • 没问题,我的朋友。 ;)
猜你喜欢
  • 1970-01-01
  • 2016-12-13
  • 2012-04-23
  • 2013-05-23
  • 1970-01-01
  • 1970-01-01
  • 2015-07-22
  • 2015-02-06
  • 1970-01-01
相关资源
最近更新 更多