Метеор: как автоматически заполнить поле длиной массива, хранящегося в другом поле в коллекции?
У меня есть коллекция, определенная с помощью SimpleSchema/Collection2, например:
Schema.Stuff = new SimpleSchema({
pieces: {
type: [Boolean],
},
num_pieces: {
type: Number,
},
Как я могу получить num_pieces
автоматически заполняется длиной pieces
массив, когда есть изменение?
Я открыт для использования SimpleSchema autoValue
или же matb33:collection-hooks
, pieces
потенциально может быть изменено с помощью нескольких операторов, таких как $push
, $pull
, $set
и, вероятно, больше, что Монго может предложить, и я понятия не имел, как справиться с этими возможностями. В идеале можно просто посмотреть на значение pieces
после обновления, но как вы можете сделать это и внести изменения, не вдаваясь в бесконечный цикл на хуке сбора?
2 ответа
Вот пример того, как вы бы выполняли ловушку для коллекции "после обновления", которая предотвращает бесконечный цикл:
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();
}
}
},
});