在Meteor中,如何在另一个字段更改时更新一个数据库字段?

med*_*nds 12 meteor

一般问题:在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订阅该集合.)

上面的代码似乎有效,但不知何故对我来说不太合适.问题:

  1. 像这样观察Lists集合是一种合理的方法吗?它似乎效率低下 - 对Lists文档的任何更改都将触发此代码.
  2. 我应该在客户端进行不同的(模拟)更新,还是可以在两者上运行相同的Mongo/Minimongo更新?
  3. 我是否需要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