Javascript 为什么全堆栈角度生成器使用Lo Dash';是否合并而不是document.set?

Javascript 为什么全堆栈角度生成器使用Lo Dash';是否合并而不是document.set?,javascript,angularjs,mongoose,yeoman,lodash,Javascript,Angularjs,Mongoose,Yeoman,Lodash,这是用于更新的默认代码: exports.update = function(req, res) { if(req.body._id) { delete req.body._id; } Thing.findById(req.params.id, function (err, thing) { if (err) { return handleError(res, err); } if(!thing) { return res.send(404); } var upd

这是用于更新的默认代码:

exports.update = function(req, res) {
  if(req.body._id) { delete req.body._id; }
  Thing.findById(req.params.id, function (err, thing) {
    if (err) { return handleError(res, err); }
    if(!thing) { return res.send(404); }
    var updated = _.merge(thing, req.body);
    updated.save(function (err) {
      if (err) { return handleError(res, err); }
      return res.json(200, thing);
    });
  });
};
注意下面这行代码:
var updated=u.merge(thing,req.body)。这仅适用于作为基本体的架构属性。它不适用于作为数组的模式属性

问题是
thing
是一个mongoose文档,
req.body
是一个javascript对象

我对真正的问题有两个假设:

  • 要求第一个参数是对象,但它是 接收文件
  • _.merge()仅当两个对象具有相同的键和类型时才会合并。因为一个是文档,另一个是对象,所以它们是 不一样
  • 考虑这个例子<代码>名称
    已正确更新,但
    arr
    未正确更新。但是,当我使用
    thing.set(req.body)
    而不是
    var updated=.\uu.merge(thing,req.body)
    时,这两个属性都得到了正确的更新

    thing.html

    <div class="container">
      <form ng-submit="update()">
        <div class="form-group">
          <label>Name</label>
          <input class="form-control" ng-model="thing.name">
        </div>
        <div class="form-group">
          <label>Arr</label>
          <input
            type="text"
            class="form-control"
            ng-repeat="el in thing.arr"
            ng-model="thing.arr[$index]">
        </div>
        <button 
          class="btn btn-default"
          type="submit">
          Update
        </button>
      </form>
    
      {{thing | json}}
    </div>
    
    thing.model.js

    'use strict';
    
    var mongoose = require('mongoose'),
        Schema = mongoose.Schema;
    
    var ThingSchema = new Schema({
      name: String,
      arr: []
    });
    
    module.exports = mongoose.model('Thing', ThingSchema);
    
    thing.controller.js(后端)

    两个问题:

  • 使用u.merge()有什么问题
  • 为什么文档的创建者选择使用u.merge()?我肯定他们知道它的行为,所以他们一定有原因
  • 您需要用户“markModified”


    对u.merge返回值调用“markModified”(正如前面的答案所建议的那样)并没有解决我的这个问题。Adam Zerner报告的问题是_merge导致“updated”对象包含数组属性的无效数据。我在使用angular fullstack generator时也遇到了这个问题,例如,如果我从数组中删除元素,则此更改不会存储在Mongoose/mongo中。调用mongoose文档上的set函数(例如,Zerner建议的thing.set(…)为我解决了这个问题。我还阅读了这个讨论线程:;它建议将_merge替换为_extend(另请参见),这也适用于我。

    我从Lodash 3.10.1升级到了4.6.1(最新版本)和u.merge现在可以按您的需要工作。我已经有一段时间遇到了这个问题,使用最新版本的generator angular fullstack(3.3.0)将u.merge更改为u.assign在以前的版本中,它对我不起作用。Lodash的v4.6.1版本似乎可以实现这一点,尽管我看到许多npm模块将Lodash的v3.10.1版本列为依赖项,但我还没有遇到任何问题。

    是-。我删除了它,因为我使用的是
    set()
    ,但我只是将其取消删除以供您参考。@JohnnyHK绝对正确!您是对的,我应该在一开始就这样做。我用新的示例编辑了这个问题。在这种情况下,您需要手动将
    arr
    字段标记为已修改,因为您尚未定义其元素包含的内容,所以Mongoose无法判断它何时被修改。
    updated.markModified('arr');
    @johnyhk好的,谢谢。你认为这比使用
    set
    有优势吗?也许它更快,因为它只是合并更新的内容,而不是所有内容?请参阅user3608315的答案
    'use strict';
    
    var mongoose = require('mongoose'),
        Schema = mongoose.Schema;
    
    var ThingSchema = new Schema({
      name: String,
      arr: []
    });
    
    module.exports = mongoose.model('Thing', ThingSchema);
    
    'use strict';
    
    var _ = require('lodash');
    var Thing = require('./thing.model');
    
    exports.update = function(req, res) {
      if(req.body._id) { delete req.body._id; }
      Thing.findById(req.params.id, function (err, thing) {
        if (err) { return handleError(res, err); }
        if(!thing) { return res.send(404); }
        var updated = _.merge(thing, req.body);
        updated.save(function (err) {
          if (err) { return handleError(res, err); }
          return res.json(200, thing);
        });
      });
    };
    
    function handleError(res, err) {
      return res.send(500, err);
    }
    
    var updated = _.merge(store, req.body);
    updated.markModified('foo_name');
    updated.save(function (err) {
      if (err) {
        return handleError(res, err);
      }
      return res.json(200, store);
    });