Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Meteor中,当另一个字段发生变化时,如何更新一个db字段?_Meteor - Fatal编程技术网

在Meteor中,当另一个字段发生变化时,如何更新一个db字段?

在Meteor中,当另一个字段发生变化时,如何更新一个db字段?,meteor,Meteor,一般问题:在Meteor中,实现在模型更新时触发的业务逻辑的最佳方式是什么?例如,更新依赖字段或验证或 具体示例:我想在列表集合中添加一个“slug”字段。每当列表名称更改时,slug需要自动更新 这是我得到的。。。我正在观察列表的每一个变化,看看它的slug是否需要创建/更新。这在shared models.js中(运行服务器和客户端,以获得延迟补偿的好处): //列出--{name:String} 列表=新流星收藏(“列表”); var listsObserver=Lists.find().

一般问题:在Meteor中,实现在模型更新时触发的业务逻辑的最佳方式是什么?例如,更新依赖字段或验证或

具体示例:我想在列表集合中添加一个“slug”字段。每当列表名称更改时,slug需要自动更新

这是我得到的。。。我正在观察列表的每一个变化,看看它的slug是否需要创建/更新。这在shared models.js中(运行服务器和客户端,以获得延迟补偿的好处):

//列出--{name:String}
列表=新流星收藏(“列表”);
var listsObserver=Lists.find().observe({
新增:updateSlug,
更改:updateSlug
});
函数updateSlug(doc,idx){
var slug=(doc.name | |').replace(/\W+/g,'-').toLowerCase();
如果(段塞!==文件段塞){
console.log(“将''+doc.name+''的slug更新为'+slug”);
更新(doc._id,{$set:{slug:slug}});
}
}
(与最初的todos示例一样,server/publish.js将所有
list.find()
发布为“列表”,而client/todos.js订阅该集合。)

上面的代码似乎可以工作,但在我看来不太正确。问题:

  • 这样观察列表集合是合理的方法吗?好像 这可能是低效的——对列表文档的任何更改都会触发此代码
  • 我应该做一个不同的(模拟的)客户端更新,还是允许 在这两个服务器上运行相同的Mongo/Minimongo更新
  • 我是否需要在某个时候调用
    listsObserver.stop()
    来处理观察者? 如果是,什么时候

  • (我刚刚开始使用Meteor,因此可能我对其他环境的偏见正在泄漏。这里隐含的元问题是,我是否以正确的方式思考这个问题?

    实现这一点的一种方法是定义自定义模板函数,并在正在更改的模板中触发它。例如:

    在client.js中

    Template.myTemplate.custom_function_to_update = function() {
        // do my update code.  i.e. MyCollections.Update(...);
    }
    
    在带有模板的html文件中

    <template name="myTemplate">
        <!-- Normal template code -->
        {{ custom_function_to_update }}
    </template>
    
    
    {{custom_function_to_update}
    

    每次模板“myTemplate”更新时,它都会调用您的方法。

    我在服务器代码中做了类似的事情。基本上,将此代码放在Meteor.methods()中,以及您希望对列表集合进行的任何其他检查和更新

    尽管下面的代码看起来有点凌乱,而且很难理解以var slug开头的代码行:

    Meteor.methods({
       myupdate: function (doc) {
    
         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}});
         }
       }
    });
    

    我建议使用收集挂钩包。它使用before和after钩子扩展了收集操作。这比拥有大量收集观察或观察更改要好,尤其是在收集观察开销可能非常大的服务器上

    这在客户端和服务器上都有效。如果您在客户端上实现它,您将获得更新本地集合(延迟补偿)的好处,并且更改将推送到服务器,因此无需再次执行

    您还可以只执行一个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);
    

    您可以在这里找到包:

    但是模板代码只在客户端运行,并且只针对特定的模板,对吗?因此,在不触发业务逻辑的情况下,变更很容易滑入模型。使用todo示例,如果只有该模板负责使list.slug保持最新,那么修改list.title的任何其他代码都会留下一个不同步的slug。这也会为每个打开该模板的客户端运行一次更新,这并不理想。嗯。。。刚刚在一个关于流星数据验证的老问题中发现。它似乎说您应该实现RPC风格的Meteor.methods进行模型编辑,然后阻止客户端的minimongo模型自动同步回服务器。(希望这还不是建议。自动、实时、双向同步是Meteor最吸引人的地方之一。)Meteor怎么知道每次有人试图修改列表名称时都要运行
    myupdate
    ?或者每个可能修改列表名称的程序员只需要知道在之后也要调用
    myupdate
    ?(我正在寻找能够自动运行并防弹的东西。)在什么情况下,您会修改列表名称?i、 e.将更改写入数据库?如果是这样的话,只需将上面的代码组合到主代码中即可。如果不让我知道,解决方案可能是使用observeChanges()将代码放入Publish()中。哇,我甚至不知道这个存在!这正是我希望在流星核心找到的。