Meteor 订阅集合中而不是模板中的更改

Meteor 订阅集合中而不是模板中的更改,meteor,Meteor,我对meteor很陌生,所以如果我遗漏了一些非常基本的东西,我深表歉意 我认为创建一个非常简单的textpad风格的应用程序来查看meteor会很有趣。我使用了todo应用程序,将数据结构更改为“文件夹”和“文档”,而不是“列表”和“todo”,因此我有一个文件夹列表,当您单击该文件夹时,您会看到该文件夹中的文档列表 然后,我添加了一些代码,以在单击列表中的一个文档时显示单个“文档”的“内容”属性 我正在使用ace向文档()的内容添加一些漂亮的打印内容。我已经将ace设置为使用一个隐藏的文本区域

我对meteor很陌生,所以如果我遗漏了一些非常基本的东西,我深表歉意

我认为创建一个非常简单的textpad风格的应用程序来查看meteor会很有趣。我使用了todo应用程序,将数据结构更改为“文件夹”和“文档”,而不是“列表”和“todo”,因此我有一个文件夹列表,当您单击该文件夹时,您会看到该文件夹中的文档列表

然后,我添加了一些代码,以在单击列表中的一个文档时显示单个“文档”的“内容”属性

我正在使用ace向文档()的内容添加一些漂亮的打印内容。我已经将ace设置为使用一个隐藏的文本区域,该区域包含我文档的纯文本版本,编辑器对象获取该文本并将其漂亮地打印出来

ace的问题是,我不希望每次文档内容更改时都替换包含ace编辑器的模板(因为重新初始化需要半秒钟,在键入每个字符后这是一种糟糕的体验!)。相反,我想更新textarea模板,然后使用ace API告诉编辑器根据textarea中的内容更新其输入

现在,这可能是解决问题的错误方法,但我最终使用了两个模板。第一个包含一个包含doc.contents的textarea,它与基础模型反应:

<template name="doc_content">
  <textarea name="editor">{{content}}</textarea>
</template>
在编辑器div中输入文本时,我调用
Docs.update(doc_id,{$set:{content:text}}),它更新每个客户端上文本区域中的值。到目前为止一切都很好

editor.getSession().on('change', function(){
    var text = editor.getSession().getValue();
    Docs.update(doc_id, {$set: {content: text}});
});
对于除进行更改的客户机以外的所有客户机,我要做的是订阅该文档的更改,并使用刚刚更改的文本调用editor.getSession().setContent(),从textarea获取文本并使用它填充编辑器

我试图通过从包含textarea的模板中进行调用来实现这一点(因为每当更新文档时,该调用都会发生变化——请参见上面的#1)。但是,这会使客户端进入无限循环,因为更改编辑器中的值会导致另一次调用
Docs.update

显然,在渲染模板时不会发生这种情况,所以我假设meteor中有一些魔法可以防止这种情况发生,但我不确定如何做到

有什么想法吗


蒂亚

你的问题有很多要理解的地方,但如果我理解正确,你可能只是在
Deps.autorun

Deps.autorun(function () {
    var doc_id = Session.get('viewing_itemname');
    if (!doc_id) {
        return {};
    }

    var doc = Docs.findOne({_id:doc_id});

    // do stuff with doc
});
Deps.autorun
非常有用,因为如果它的任何一个 依赖关系会改变。这些依赖关系仅限于“反应性”的依赖关系 例如集合和会话,或者实现反应式API的任何东西

在您的情况下,
Session.get
findOne
都是被动的,因此如果它们的值
如果进行任何更改,
Deps.autorun
将再次运行该函数。

Meteor.autorun更适合我上面给出的示例现在是Deps.autorun
editor.getSession().on('change', function(){
    var text = editor.getSession().getValue();
    Docs.update(doc_id, {$set: {content: text}});
});
Deps.autorun(function () {
    var doc_id = Session.get('viewing_itemname');
    if (!doc_id) {
        return {};
    }

    var doc = Docs.findOne({_id:doc_id});

    // do stuff with doc
});