一般问题:在Meteor中,实现在更新模型时触发的业务逻辑的最佳方式是什么 - 例如,用于更新相关字段或验证或...
具体示例:我想在Meteor todos示例中向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}});
}
}
Run Code Online (Sandbox Code Playgroud)
(和最初的todos示例一样,server/publish.js将所有内容发布Lists.find()为"lists",client/todos.js订阅该集合.)
上面的代码似乎有效,但不知何故对我来说不太合适.问题:
listsObserver.stop()在某个时候打电话处理观察员?若然,何时?(我刚刚开始使用Meteor,所以也许我在其他环境中的偏见正在泄漏.这里隐含的元问题是,我是否正在以正确的方式思考这个问题?)
Dsy*_*yko 12
我建议使用Collection-Hooks包.它扩展了钩子前后的收集操作.这比拥有大量Observes或ObserveChanges更好,特别是在收集观察的开销可能变得非常大的服务器上.
这适用于客户端和服务器.如果您在客户端上实现它,您将获得更新本地集合(延迟补偿)的好处,并且更改将被推送到服务器,因此无需再次执行此操作.
您还可以获得仅执行一次MongoDB操作而不是两次或更多操作的好处,就像使用observes或observeChanges一样.
您可以像这样使用它:
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);
Run Code Online (Sandbox Code Playgroud)
你可以在这里找到这个软件包:https://atmospherejs.com/matb33/collection-hooks