将新评论推送到 mongoose/mongodb/angularjs 中的评论数组中

Posted

技术标签:

【中文标题】将新评论推送到 mongoose/mongodb/angularjs 中的评论数组中【英文标题】:push new comments into comments array in mongoose/mongodb/angularjs 【发布时间】:2016-08-09 06:59:37 【问题描述】:

过去 3 天我一直在尝试使用 yo 生成的 crud 模块将新的评论对象推送到我的 cmets 数组中。

这是我的 cmets 架构的 server.model,我将其用作子文档:

var CommentsSchema = new Schema(

comment: 
    type: String,
    default: ''
,
user: 
    type: Schema.ObjectId,
    ref: 'User'
,
created: 
    type: Date,
    default: Date.now

);
mongoose.model('Comments', CommentsSchema);

这是任务架构,我在其中包含了 cmets 架构:

var TaskSchema = new Schema(
name: 
    type: String,
    default: '',
    required: 'Please fill Task name',
    trim: true
,
created: 
    type: Date,
    default: Date.now
,
user: 
    type: Schema.ObjectId,
    ref: 'User'
,
//comments : [
  //  text:  type: String ,
//    created:  type: Date, default: Date.now ,
  //  user:  type: Schema.ObjectId, ref: 'User' 
//]
comments: [CommentsSchema]
);
mongoose.model('Task', TaskSchema);

我可以使用 mongodb shell 手动将 cmets 插入任务中,如下所示:

db.tasks.update("_id" : ObjectId("5711856735e9cb1938845048"), $addToSet:  comments:  "comment" : "i am also a comment"      )

但是我正在努力使用 js/angularjs 中的函数设置正确的函数以插入到客户端的任务中。

我已经设置了一个表单来添加新评论:

<form name="vm.form.taskForm" class="form-horizontal" ng-submit="vm.newCo(vm.form.taskForm.$valid)" novalidate>    
<input type="text" ng-model="vm.task.comments.comment" name="comments" id="comments" placeholder="ask a question about this task">
<button type="submit">Add a comment</button>
</form>

我已经像这样更新了我的 app.routes:

app.route('/api/tasks/:taskId').all(tasksPolicy.isAllowed)
.get(tasks.read)
.put(tasks.update)
.delete(tasks.delete)
.put(tasks.newCo); // this is the new function I am trying to add

并尝试在我的 server.controller 中设置功能

exports.newCo = function(req, res) 
var task = req.task;
var task_id = req.task._id;
Task.findByIdAndUpdate(
task_id,
 $push :  comments: req.task.comments ,
 safe: true, upsert: true,
    function(err) 
        if(err) 
            console.log(err, Task);
        
        return res.json(Task);
    
)

我不太明白如何将 client.controller 与 server.controller 通信以执行更新任务并将评论推送到数组中的功能。

我对 client.controller 的最新尝试是:

function newCo(isValid) 
        if (!isValid) 
            $scope.$broadcast('show-errors-check-validity', 'vm.form.taskForm');
                return false;
        
        if (vm.task._id) 
                vm.task.$newCo(successCallback, errorCallback);
             else 
                vm.task.$save(successCallback, errorCallback);
            

        function successCallback(res) 
                $state.go('tasks.view', 
                    taskId: res._id
                );
            

            function errorCallback(res) 
                vm.error = res.data.message;
            
    

如果有人能指出我正确的方向,我会非常感激!谢谢大家!

例如,这就是 remove() 的工作方式

client.controller

// Remove existing Task
    function remove() 
            if (confirm('Are you sure you want to delete?')) 
                vm.task.$remove($state.go('tasks.list'));
            
        

服务器.控制器

exports.delete = function(req, res) 
    var task = req.task;
    task.remove(function(err) 
        if (err) 
            return res.status(400).send(
                message: errorHandler.getErrorMessage(err)
            );
         else 
            res.jsonp(task);
        
    );
;

server.routes.js

  app.route('/api/tasks/:taskId').all(tasksPolicy.isAllowed)
    .get(tasks.read)
    .put(tasks.update)
    **.delete(tasks.delete)**

最后是 html 视图:

<a class="btn btn-primary" data-ng-click="vm.remove()">
  <i class="glyphicon glyphicon-trash"></i>
</a>

【问题讨论】:

【参考方案1】:

你可以按照这个过程:

在html中:

您不需要在newCo 函数中传递vm.form.taskForm.$valid 可以从表单中检查。如果表单无效ng-disabled="vm.form.taskForm.$invalid",提交按钮可以保持禁用。也可以使用ng-model="vm.task.newComment" 而不是ng-model="vm.task.comments.comment",因为你想添加新评论所以不需要使用comments.comment。所以可以像这样使用html:

<form name="vm.form.taskForm" class="form-horizontal" ng-submit="vm.newCo()" novalidate>
    <input type="text" ng-model="vm.task.newComment" name="comments" id="comments" placeholder="ask a question about this task">
    <button type="submit" ng-disabled="vm.form.taskForm.$invalid">Add a comment</button>
</form>

我猜你使用 controller as 就像 ng-controller="yourCtrl as vm" 或者在路由提供者中使用像 controllerAs: 'vm'

在您的控制器中:

var vm = this;
vm.task = task //predefined
vm.newCo = function() 
  // used $http.put('/api/tasks/21' according to your server side route
  $http.put('/api/tasks/21', 
    comment: vm.task.newComment;
  ).then(successCallback, errorCallback); //say 21 is taskId

  function successCallback(res) 
    $state.go('tasks.view', 
      taskId: res.data._id
    );
  

  function errorCallback(res) 
    vm.error = res.data.message;
  
;

服务器端控制器:

exports.newCo = function(req, res) 
  Task.findOneAndUpdate(_id: req.params.taskId, 
    
      "$push": 
        comments: req.body.comment
      
    , 
      new: true //to return updated document
    )
    .exec(function(error, task) 
      if (error) 
        return res.status(400).send(message: 'Failed to add comment due to invalid params!');
      
      return res.status(200).send(task);
    );
;

并且在您的架构中应该使用Schema.Types.ObjectId 而不是Schema.ObjectId

user: 
    type: Schema.Types.ObjectId,
    ref: 'User'

【讨论】:

嘿@shaishab roy 非常感谢您的意见。我已经尝试过你的建议,但是 jshint 在运行 grunt 时抛出了一些错误。我想知道您是否对函数中没有 $http.put('/api/tasks/21', 的客户端有建议。例如,我在编辑中添加的删除功能 好的,你能在 plunker 中显示你的完整控制器和 ui 以更好地理解@loulala 我对客户端控制器做了一些微调,现在我成功地推入了阵列。非常感谢@shaishab 我试图为另一个表单复制该函数,但是每次我按下提交它都会将一个空值推送到我的 cmets 数组,而不是我的新数组。我已经重命名了函数并更改了客户端控制器的变量和服务器端的 req.body,你知道为什么会发生这种情况吗? 您能否展示您的$http.put(.. 方法以及在服务器端如何接收? @loulala

以上是关于将新评论推送到 mongoose/mongodb/angularjs 中的评论数组中的主要内容,如果未能解决你的问题,请参考以下文章

postgresql 函数 - 如何将新的 json 对象推送到 json 数组?

如何将新值推送到 Store 对象?

Mongoose 无法将新对象推送到父数组

将新数据推送到firebase数据库时设置自定义数字键

Mongoose:如何将新值推送到特定键中?

无法将新存储库推送到 github