【问题标题】:Save records into the same collection in Mongo DB using Meteor js使用 Meteor js 将记录保存到 Mongo DB 中的同一集合中
【发布时间】:2017-10-25 05:08:00
【问题描述】:

作为 Meteor JS 的新手,我对如何更新记录感到困惑。我有 2 个模板 AddSchoolLayout 和 Schoolcontactlayout,AddSchoollayout 在 Mongo db 中创建记录,现在,对于同一所学校,我想在同一个 DB NewSchoolDB 上添加它的地址,但是当我尝试这个时,我不断收到下面关于错误 ID 的错误。我有什么错?

请注意,我的语言可能与 Mongo 的语言不相关;我还很新鲜,来自 SQL 背景。

这是保存记录的method.js。

//methods.js
    if (Meteor.isServer) {
        Meteor.methods({
            SchoolRegister: function (phone, schoolemail) {
                if (!Meteor.userId()) {
                    throw new Meteor.error('Not authorized');
                    return false;
                }else{

                    NewSchoolDB.insert({
                        authorId: Meteor.userId(),
                        phone: phone,
                        schoolemail
                    });
                }
            }
        });
    }

这是拯救新学校的活动

//add school
Template.AddSchoolLayout.events({
    'submit .addnewschool': function (event, template) {
        event.preventDefault();

        var newschoolname = trimInput(event.target.newschoolname.value);

        if (isNotEmpty(newschoolname)) {

            Meteor.call('SchoolRegister', newschoolname,
                function (error, response) {
                    if (error) {
                        Bert.alert(error.reason, 'danger', 'growl-top-right');
                        return false;
                    }else{
                        Bert.alert("School successfully created", "success", "growl-top-right");
                        FlowRouter.redirect('/schoolcontact');
                    }
                });

        }
        return false;
    }
});

这是我要更新学校地址的地方

//school contact
Template.SchoolContactLayout.events({
    'submit .contactschool': function (event) {
        event.preventDefault();

        var phone = trimInput(event.target.phone.value);    
        if (isNotEmpty(phone)) {
            Meteor.call('SchoolRegister', phone, function (error, response) {
                if (error) {
                    Bert.alert(error.reason, 'danger', 'growl-top-right');
                    return false;
                }else{
                    Bert.alert('School address updated successfully', 'success', 'growl-top-right');
                    FlowRouter.redirect('/logo-upload');
                }
            });
        }
        return false;
    }
});

控制台记录错误

I20170524-17:44:14.051(1)?     at packages/ddp-server/livedata_server.js:559:43
I20170524-17:51:54.678(1)? Exception from sub NewSchoolDB id onFTu2j3xRmbqC5WF TypeError: this.userId is not a function
I20170524-17:51:54.710(1)?     at [object Object]._handler (lib/pulbish/published.js:3:13)
I20170524-17:51:54.712(1)?     at maybeAuditArgumentChecks (packages/ddp-server/livedata_server.js:1737:12)
I20170524-17:51:54.713(1)?     at [object Object]._.extend._runHandler (packages/ddp-server/livedata_server.js:1035:17)
I20170524-17:51:54.714(1)?     at [object Object]._.extend._startSubscription (packages/ddp-server/livedata_server.js:853:9)
I20170524-17:51:54.715(1)?     at [object Object]._.extend.protocol_handlers.sub (packages/ddp-server/livedata_server.js:625:12)
I20170524-17:51:54.719(1)?     at packages/ddp-server/livedata_server.js:559:43

【问题讨论】:

标签: mongodb templates meteor meteor-blaze minimongo


【解决方案1】:

您的 SchoolRegister 方法接受 2 个参数:phoneschoolmail。创建学校时,您使用一个名为newschoolname 的参数调用方法。因此,您的命名约定有问题,但与您的问题无关。

使用 MongoDB,您可以使用 insert 将新记录添加到您的集合中。如果您需要更新它,请使用更新。因此,解决您的问题的一种方法是:

  • 在 AddSchoolLayout 中,调用您的方法以第一次插入文档。 NewSchoolDB.insert(...) 将返回创建记录的 ID。保留该 ID 并将其传递到您的下一页,例如在 URL 中。
  • 在您的下一页SchoolContactLayout 中,您需要调用一个新方法,该方法将使用前一个方法返回的 ID 来更新您的学校。这个新方法看起来像这样:

    SchoolUpdate: function (schoolId, phone) {
        if (!Meteor.userId()) {
            throw new Meteor.error('Not authorized');
            return false;
        }else{
            NewSchoolDB.update(schoolId, { $set: { phone } });
        }
    }
    

更新 MongoDB 函数的第一个参数是要更新的记录的 ID。第二个参数是您要用于更新记录的修饰符。以下是您可以使用的修饰符的完整列表:update modifiers

编辑:如何将 ID 从一种布局传递到另一种布局:

我有一段时间没有使用 FlowRouter,现在无法对其进行测试,因此您可能需要进行一些更正,但为了给您一个想法,我会这样做:

首先你需要定义你的路线SchoolContactLayout,如下所示:

FlowRouter.route('/schoolcontact/:schoolId', {
  name: 'schoolContact',
});

这会在路由中添加一个schoolId 参数。

在你的 SchoolRegister 方法中,获取返回 ID 并返回:

var id = NewSchoolDB.insert({
  authorId: Meteor.userId(),
  schooleName
});
return { id }

使用FlowRouter.go('/schoolcontact/' + response.id); 编辑您的重定向FlowRouter.redirect('/schoolcontact');

然后,您可以使用以下内容编辑您的 contactSchool 事件:

Template.SchoolContactLayout.events({
  'submit .contactschool': function (event) {
     event.preventDefault();

     var schoolId = FlowRouter.getParam('schoolId');
     var phone = trimInput(event.target.phone.value);    
     if (isNotEmpty(phone)) {
       Meteor.call('SchoolUpdate', schoolId ,phone, function (error, response) {
         if (error) {
           Bert.alert(error.reason, 'danger', 'growl-top-right');
           return false;
         }else{
           Bert.alert('School address updated successfully', 'success', 
            'growl-top-right');
           FlowRouter.redirect('/logo-upload');
         }
       });
     }
     return false;
   }
 });

注意 var schoolId = FlowRouter.getParam('schoolId'); 从 URL 参数中获取 ID,以便我可以在更新方法中使用它。

【讨论】:

  • 谢谢。这是在正确的方向,我的下一个问题是我如何传递ID。应该在会话中吗?
  • 非常感谢。我使用 session 来获取 id,因为它是一个全局变量并被检索。有效。这有什么副作用吗?
  • 如果您可以尽可能多地使用作用域变量而不是全局变量,通常会被认为更好,这样您就可以对它进行更多的“控制”。使用 session 你需要更多地管理变量(设置它,删除它,替换它),因为它是全局的,你并不总是真的确定里面的值是什么。但在你的情况下,它应该没有太多问题。全局变量往往是大型项目的问题。 :)
  • 非常感谢您提供如此出色的专业见解。随着事情的发展和应用程序的扩展,我会及时通知您。
  • 假设文档ID是一个名为docId的变量,那么它就像return NewSchoolDB.findOne({_id: docId});一样简单。 Here is the doc。请注意每条记录都有一个名为 _id 而不是 id 的 ID。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-20
  • 1970-01-01
  • 2015-10-07
  • 2016-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多