如何在中间件函数中迭代Mongoose模型属性?

时间:2014-06-30 15:16:35

标签: javascript loops mongoose

我正在尝试在中间件函数中迭代mongoose模型中的字段。当前上下文this是模型对象本身。所以我有一个函数,其中上下文是这样的Javascript对象:

{
  lastName: 'Wilkens',
  firstName: 'Elepart',
  name: 'Elepart Wilkens',
  username: 'eK',
  bio: '<script>alert(\'this is a hack!!\')',
  _id: 53b17dd0e8c5af50c1d73bc6,
  language: 'en',
  country: 'USA',
  online: true
}

我想迭代这个对象(用this表示在当前函数中)。每次我尝试使用循环进行迭代时,它都会打印出看起来像内部Javascript元数据的值。如果this表示对象,是否可以在函数内迭代this

这是实际的中间件功能:

userSchema.pre('save', function (next) {
    console.log(this); // This prints precisely the same object I have copied above

    var fields = Object.keys(this);

    for(var i = 0; i < fields.length; i++) {
        console.log(this[fields[i]]);
    }

    for(var key in this) {
      if(this.hasOwnProperty(key)) {
        console.log(this[key]);
      }
    }
});

输出是:

{ 
 strictMode: true,
 selected: undefined,
 shardval: undefined,
 saveError: undefined,
 validationError: undefined,
 adhocPaths: undefined,
 removing: undefined,
 inserting: undefined,
 version: undefined,
 getters: {},
 _id: undefined,
 populate: undefined,
 populated: undefined,
 wasPopulated: false,
 scope: undefined,
 activePaths: 
   { paths: 
      { username: 'modify',
        firstName: 'modify',
        name: 'modify',
        online: 'default',
        country: 'default',
        language: 'default',
        _id: 'default',
        bio: 'modify',
        lastName: 'modify' },
     states: { default: [Object], init: {}, modify: [Object], require: {} },
     stateNames: [ 'require', 'modify', 'init', 'default' ],
     map: [Function] },
  ownerDocument: undefined,
  fullPath: undefined }
true
undefined
0
{ online: true,
  country: 'USA',
  language: 'en',
  _id: 53b1825a00ed9af7c12eedf9,
  bio: '<script>alert(\'this is a hack!!\')',
  username: 'yK',
  name: 'Yershay Wilkens',
  firstName: 'Yershay',
  lastName: 'Wilkens' }
{ save: 
   [ { [Function] isAsync: false },
     { [Function: checkForExistingErrors] isAsync: false },
     { [Function: validation] isAsync: false },
     { [Function] isAsync: false },
     { [Function] isAsync: false } ],
  validate: [ { [Function] isAsync: false } ] }
{ save: [], validate: [] }
{ [Function] numAsyncPres: 0 }
{ [Function] numAsyncPres: 0 }
{}

3 个答案:

答案 0 :(得分:6)

您使用整数索引而不是字段数组中的字符串引用。它应该是:

var fields = Object.keys(this);

for(var i = 0; i < fields.length; i++) {
    console.log(this[fields[i]]);
}

(例如,您正在执行this[1]this[2],而不是this[fields[1]]

答案 1 :(得分:4)

我发现了一种稍微不同的方法来实现我想要的方法,即在中间件函数中迭代Mongoose模型的模型属性。这使用async.js,但您可以重构它以使用通用JS循环或任何其他控制流库。关键是获取文档字段的数组,然后您可以使用this使用当前上下文迭代这些字段并获取/设置值。据我所知,这将 将非字符串值强制转换为字符串。我用字符串,数字,布尔值和objectIds对它进行了测试,并将它们成功保存为原始数据类型。

yourSchema.pre('save', function (next) {
  var self = this;

  // Get the document's fields
  var fields = Object.keys(this._doc);

  // Do whatever you want for each field
  async.each(fields, function(field, cb) {
    self[field] = validator.escape(self[field]);
    cb();
  }, function(err){
    next();
  });
});

答案 2 :(得分:1)

@ JohnnyHK的评论为我工作:

const user = new User();
const schemaKeys = Object.keys(user.toObject());