我对 meteor 很陌生,所以如果我在这里遗漏了一些非常基本的东西,我深表歉意。
我认为创建一个非常简单的文本板样式的应用程序来检查 meteor 会很有趣。我使用了 todo 应用程序并将数据结构更改为“文件夹”和“文档”而不是“列表”和“待办事项”,所以我有一个文件夹列表,当你点击文件夹时,你会得到一个文档列表在那个文件夹中。
然后,当单击列表中的一个文档时,我添加了一些代码来显示单个“文档”的“内容”属性。
我正在使用 ace 为文档的内容添加一些 pretty-print ( https://github.com/ajaxorg/ace )。我已经将 ace 设置为使用包含我的文档的纯文本版本的隐藏文本区域,并且编辑器对象获取此文本并漂亮地打印它。
ace 的问题是,我不希望每次文档内容更改时都替换包含 ace 编辑器的模板(因为重新初始化需要半秒钟,在输入每个字符后这是一种糟糕的体验!) .相反,我想更新 textarea 模板,然后使用 ace API 告诉编辑器根据 textarea 中的内容更新它的输入。
现在,这可能是解决问题的错误方法,但我最终使用了两个模板。第一个包含一个包含 doc.contents 的 textarea,它对底层模型是 react 性的:
<template name="doc_content">
<textarea name="editor">{{content}}</textarea>
</template>
第二个包含 ace 用来显示 pretty-print 文本的“编辑器”div。
<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 的模板中进行调用来做到这一点(因为每当更新文档时它都会改变 - 请参见上面的 #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
真的很有用,如果它的任何一个它都会重新运行依赖改变。这些依赖关系仅限于那些“ react 性”的
例如 Collections 和 Sessions,或者任何实现响应式 API 的东西。
在您的情况下,
Session.get
和 findOne
是 react 性的,所以如果它们的值完全改变,
Deps.autorun
将再次运行该功能。
关于meteor - 订阅集合中的更改但不在模板中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10201106/