流星:如何使用存储在集合中其他字段中的数组长度自动填充字段?

Meteor: how to automatically populate field with length of array stored in other field in a collection?

我有一个用 SimpleSchema/Collection2 定义的集合,如下所示:

Schema.Stuff = new SimpleSchema({
    pieces: {
        type: [Boolean],
    },
    num_pieces: {
        type: Number,
    },

如何让 num_pieces 在发生变化时自动填充 pieces 数组的长度?

我愿意使用 SimpleSchema 的 autoValuematb33:collection-hookspieces 可能会被相当多的运算符改变,例如 $push$pull$set,可能更多 Mongo 必须提供,我不知道如何应对这些可能性。理想情况下,人们只会在更新后查看 pieces 的值,但是您如何才能做到这一点并进行更改而不进入收集挂钩上的无限循环呢?

下面是一个示例,说明如何执行收集挂钩 'after update' 以防止无限循环:

Stuff.after.update(function (userId, doc, fieldNames, modifier, options) {
  if( (!this.previous.pieces && doc.pieces) || (this.previous.pieces.length !== doc.pieces.length ) {
    // Two cases to be in here:
    // 1. We didn't have pieces before, but we do now.
    // 2. We had pieces previous and now, but the values are different.
    Stuff.update({ _id: doc._id }, { $set: { num_pieces: doc.pieces.length } });
  }
});

请注意,this.previous 允许您访问上一个文档,doc 是当前文档。这应该足以让您完成其余的案例。

您也可以直接在架构中完成

Schema.Stuff = new SimpleSchema({
  pieces: {
    type: [Boolean],
  },
  num_pieces: {
    type: Number,
    autoValue() {
      const pieces = this.field('pieces');
      if (pieces.isSet) {
        return pieces.value.length
      } else {
        this.unset();
      }
    }    
  },
});