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

时间:2012-04-18 00:27:01

标签: meteor

我对流星很新,如果我在这里遗漏了一些非常基本的东西,请道歉。

我认为创建一个非常简单的文本板样式应用来检查流星会很有趣。我拿了todo应用程序并将数据结构更改为'文件夹'和' docs'而不是'列表'和&#t; todos',所以我有一个文件夹列表,当你点击该文件夹时,你会得到该文件夹​​中的文件列表。

然后,我添加了一些代码来显示内容'单个' doc'的属性单击列表中的某个文档时。

我使用ace为doc(https://github.com/ajaxorg/ace)的内容添加一些漂亮的印刷品。我已设置ace以使用包含我的文档的纯文本版本的隐藏文本区域,编辑器对象将使用此文本并将其打印出来。

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

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

<template name="doc_content">
  <textarea name="editor">{{content}}</textarea>
</template>

第二个包含&#39;编辑器&#39; ace用来显示漂亮的印刷文本。

<template name="doc_init">
  <div id="editor"></div>
</template> 

我们的想法是,每次用户输入时,第一个模板都会更新(在所有客户端上),而第二个模板只会为我们加载的每个新文档重新加载。

Template.doc_content.content = function() {
  var doc_id = Session.get('viewing_itemname');
  if (!doc_id) {
    return {}; 
  }

  var doc = Docs.findOne({_id:doc_id});
  if (doc && doc.content) {
    // #1 Later
    var editor = Session.get('editor');
    if (editor) {
      editor.getSession().setValue(doc.content);
    }   

    return doc.content;
  } else {
    return ''; 
  }
};

当你在编辑器div中输入文本时,我打电话给Docs.update(doc_id, {$set: {content: text}});,它会更新每个客户端上textarea的值。到目前为止一切都很好。

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

显然,当你渲染一个模板时,这并不会发生,所以我假设流星有一些魔法可以防止这种情况发生,但我不确定如何。< / p>

有什么想法吗?

TIA!

1 个答案:

答案 0 :(得分:4)

在你的问题中有很多东西要吸收,但如果我理解正确,你可能只是在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.getfindOne都是被动的,所以如果它们的值 完全改变,Deps.autorun将再次运行该功能。