简体   繁体   English

如何使用AngularJS推送到MongoDB数组?

[英]How to push to a MongoDB array with AngularJS?

I'm trying to append a bunch of comments to a MongoDB array with AngularJS's $http service, but I seem to have hit a dead end. 我正在尝试使用AngularJS的$ http服务向MongoDB数组添加一堆注释,但是我似乎陷入了死胡同。 Here is the code I tried (which crashed my DOM): 这是我尝试的代码(使我的DOM崩溃):

$scope.saveComment = function(i){
      console.log("id is " + i);
      $http.put('/api/its/' + i, { comments: {$push: { words: $scope.comment, userId: $scope.getCurrentUser().name } } } ).success(function(stuff){
         document.location.reload(true);
       })
    }

I was trying to use MongoDB's $push method to do this, but Angular won't have it. 我试图使用MongoDB的$push方法来做到这一点,但是Angular却没有。 Any clue as to how I could do this? 关于我该怎么做的任何线索?

Sincerely, 此致

Peter 彼得

PS PS

Here is the server-side code for that particular model's update functionality : 这是该特定模型的更新功能的服务器端代码:

// Updates an existing it in the DB.
exports.update = function(req, res) {
  if(req.body._id) { delete req.body._id; }
  It.findById(req.params.id, function (err, it) {
    if (err) { return handleError(res, err); }
    if(!it) { return res.send(404); }
    var updated = _.merge(it, req.body);
    updated.save(function (err) {
      if (err) { return handleError(res, err); }
      return res.json(200, it);
    });
  });
};`

There are a couple of things in here that are not great, but first to cover the basics and get you going. 这里有几件不好的事情,但是首先要涵盖基础知识并帮助您入门。

The first thing is to fix the method calling the service angular side. 第一件事是修复调用服务角度侧的方法。 The API endpoint certainly does not expect the MongoDB update syntax you are using, but rather just an object. API终结点当然不希望您使用的是MongoDB更新语法,而只是一个对象。 So first fixing that: 因此,首先解决该问题:

$scope.saveComment = function(i){
    console.log("id is " + i);

    // Split these out so they are easy to log and debug
    var path = '/api/its' + i;

    // This must mirror the structure expected in your document for the element
    // Therefore "comments" is represented as an array of objects, even
    // where this is only one.
    var data = { 
       comments: [{ 
         words: $scope.comment,
         userId: $scope.getCurrentUser().name 
       }]
    };

    // Call service with response
    $http.put(path,data).success(function(stuff){
      document.location.reload(true);
    });
}

Now your server API end has some faults, I would prefer a total redesign, but in lack of info, just concentrating on fixing the main problems without changing much. 现在您的服务器API端出现了一些故障,我希望进行全面的重新设计,但是由于缺乏信息,所以只专注于解决主要问题而不进行太多更改。

Assuming this is the lodash library, the .merge() function here is implemented incorrectly. 假设这是lodash库,则此处的.merge()函数未正确实现。 It needs to be told how to "handle" the array content in the "merge" properly, and at present the best that will happen is an "overwrite". 需要告诉我们如何正确“处理”“合并”中的数组内容,目前最好的做法是“覆盖”。 So we give it some smarts: 因此,我们给了它一些技巧:

// Updates an existing it in the DB.
exports.update = function(req, res) {
  if(req.body._id) { delete req.body._id; }
  It.findById(req.params.id, function (err, it) {
    if (err) { return handleError(res, err); }
    if(!it) { return res.send(404); }
    var updated = _.merge(it, req.body,function(a,b) {
        if (_.isArray(a)) {
            return a.concat(b);    // join source and input
        }
    });
    updated.save(function (err) {
      if (err) { return handleError(res, err); }
      return res.json(200, updated);
    });
  });
};`

But there is a catch to that, as it will only "append" to the array. 但是有一个陷阱,因为它只会“附加”到数组中。 So if you put something in your input that was already there, then both the original items and anything in the array input would be added. 因此,如果您在输入中添加了已经存在的内容,那么原始项目和数组输入中的任何内容都将被添加。

Dealing with that is a whole other issue to work out, depending on your needs. 根据您的需要,解决该问题是另一个完全问题。

From my own perpective, I would just send the array where possible and have an endpoint that is "just" for appending to the array of the document, rather than a "generic" document update as you have here. 从我自己的角度来看,我只会在可能的情况下发送该数组,并具有一个“正好”用于附加到文档数组的终结点,而不是像在此处那样对“通用”文档进行更新。

This allows you to better utilize the MongoDB update functions, per expected actions. 这样,您可以按照预期的操作更好地利用MongoDB更新功能。 So something like this in the service call: 所以在服务调用中是这样的:

// comment can just be a singular object now
$http.put(path,{ 
    "words": "this that", 
    "userId": 123
}).success(function(stuff){

And on the server API end: 在服务器API端:

exports.addComment = function(req, res) {
  if(req.body._id) { delete req.body._id; }
  It.findByIdAndUpdate(req.params.id,
     { "$push": { "comments": req.body } },
     { "new": true },
     function(err,it) {
      if (err) { return handleError(res, err); }
      if(!it) { return res.send(404); }
      return res.json(200, it);
     }
  );
};

So that will simply take the body of a "comment" and append it to the array. 这样就可以简单地将“注释”的主体添加到数组中。 Most importantly it does this "atomically", so that no other possible request could collide in doing something like the current "merge" is doing. 最重要的是,它“原子地”执行此操作,因此在执行当前“合并”操作时,其他任何可能的请求都不会发生冲突。 Other requests to the same endpoint will just "append" to the array in the current state as when the request is made, and so will this. 发出相同请求时,对同一端点的其他请求将仅在当前状态下“追加”到数组,因此也是如此。

That is what the $push operator is for, so it's wise to use it. 这就是$push运算符的用途,因此使用它是明智的。

Some food for thought. 一些思考的食物。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM