一般问题:在 Meteor 中,实现在模型更新时触发的业务逻辑的最佳方式是什么——例如,用于更新依赖字段或验证或......
具体示例:我想在 Meteor todos example 的 Lists 集合中添加一个“slug”字段。 .每当列表的名称更改时,slug 需要自动更新。
这就是我所拥有的......我正在观察列表的每一个变化,看看是否需要创建/更新它的 slug。这是在共享的 models.js 中(运行服务器和客户端,以获得延迟补偿的好处):
// Lists -- {name: String}
Lists = new Meteor.Collection("lists");
var listsObserver = Lists.find().observe({
added: updateSlug,
changed: updateSlug
});
function updateSlug(doc, idx) {
var slug = (doc.name || '').replace(/\W+/g, '-').toLowerCase();
if (slug !== doc.slug) {
console.log("Updating slug for '" + doc.name + "' to " + slug);
Lists.update(doc._id, {$set: {slug: slug}});
}
}
(和最初的 todos 示例一样,server/publish.js 将所有
Lists.find()
发布为“列表”,并且 client/todos.js 订阅该集合。)上面的代码似乎可以工作,但对我来说似乎不太合适。问题:
它可能效率低下——对 Lists 文档的任何更改都会触发此代码。
这个相同的 Mongo/Minimongo 更新在两者上运行?
listsObserver.stop()
在某个时候处置观察者?如果是这样,什么时候?
(我刚刚开始使用 Meteor,所以也许我对其他环境的偏见正在泄漏。这里隐含的元问题是,我是否以正确的方式思考这个问题?)
最佳答案
我建议使用 Collection-Hooks 包。它使用 before 和 after 钩子(Hook)扩展了收集操作。这比拥有大量的 collection Observes 或 ObserveChanges 要好,尤其是在收集观察的开销会变得非常大的服务器上。
这适用于客户端和服务器。如果您在客户端上实现它,您将获得更新本地集合(延迟补偿)的好处,并且更改将被推送到服务器,因此无需再次执行此操作。
您还可以获得只执行一个 MongoDB 操作而不是像使用观察或观察更改那样执行两个或更多操作的好处。
你可以像这样使用它:
var beforeInsertSlug = function(userId, doc) {
var slug = (doc.name || '').replace(/\W+/g, '-').toLowerCase();
if (slug !== doc.slug) {
console.log("Updating slug for '" + doc.name + "' to " + slug);
doc.slug = slug;
}
};
var beforeUpdateSlug = function(userId, doc, fieldNames, modifier, options){
if(modifier && modifier.$set && modifier.$set.doc && _.isString(modifier.$set.doc.name)){
var slug = (modifier.$set.doc.name || '').replace(/\W+/g, '-').toLowerCase();
if (slug !== doc.slug) {
console.log("Updating slug for '" + modifier.$set.doc.name + "' to " + slug);
modifier.$set.doc.slug = slug;
}
}
};
Lists.before.insert(beforeInsertSlug);
Lists.before.update(beforeUpdateSlug);
您可以在这里找到包裹:https://atmospherejs.com/matb33/collection-hooks
关于meteor - 在 Meteor 中,如何在另一个字段更改时更新一个 db 字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12464451/