Javascript Meteor:循环模板的模板级订阅或当所有订阅完成时
这就是我如何生成一篇包含介绍文本和元素列表的文章,这些元素嵌套在多层结构中。主要数据(标题、简介)由模板级订阅加载。加载数据时,将显示一个微调器。到目前为止,这是有效的 现在,我正在使用另一个模板加载一个嵌套列表,该模板将被循环以获取所有需要的数据。数据以带有父引用的模型树结构进行结构化。因此,对于每个循环,都会加载子循环并将其添加到列表中。这意味着如果列表深入三层,模板将被使用三次 我的问题是:Javascript Meteor:循环模板的模板级订阅或当所有订阅完成时,javascript,jquery,meteor,Javascript,Jquery,Meteor,这就是我如何生成一篇包含介绍文本和元素列表的文章,这些元素嵌套在多层结构中。主要数据(标题、简介)由模板级订阅加载。加载数据时,将显示一个微调器。到目前为止,这是有效的 现在,我正在使用另一个模板加载一个嵌套列表,该模板将被循环以获取所有需要的数据。数据以带有父引用的模型树结构进行结构化。因此,对于每个循环,都会加载子循环并将其添加到列表中。这意味着如果列表深入三层,模板将被使用三次 我的问题是: 每个“循环”都会导致一个新的subscribe and find()请求获取该级别的元素。是否可以
autosize()
添加到该列表中显示的所有文本区域中,那么如果我添加Template.elements.onRendered(function(){$('textarea').autosize();}),则它不起作用代码>因为最后的元素不受影响。我不明白为什么
<template name="article">
{{#if Template.subscriptionsReady}}
<h1>{{article.title}}</h1>
<p>{{article.intro}}</p>
{{ > elements article._id }}
{{else}}
<div class="loading">{{ > spinner }}</div>
{{/if}}
</template>
<template name="elements">
<ul>
{{#each elements}}
<li>
<textarea>{{title}}</textarea>
{{ > elements _id }}
</li
{{/each}}
</ul>
</template>
Template.article.helpers({
article: function() { return Template.instance().article(); }
});
Template.elements.helpers({
children: function(parentId) {
Meteor.subscribe('elements', parentId);
return Collection.find({ parent: parentId }, { sort: { order: 1 } });
}
});
一旦创建
Template.article.onCreated(function() {
var instance = this;
instance.autorun(function () {
var subscription = instance.subscribe('article', Session.get('docId'));
});
instance.article = function() { return Collection.findOne({ _id: Session.get('docId') }); };
});
Template.elements.onRendered(function() {
$('textarea').autosize();
});
onRendered
Template.article.onCreated(function() {
var instance = this;
instance.autorun(function () {
var subscription = instance.subscribe('article', Session.get('docId'));
});
instance.article = function() { return Collection.findOne({ _id: Session.get('docId') }); };
});
Template.elements.onRendered(function() {
$('textarea').autosize();
});
以下是数据库中数据的结构:
{
"_id" : "YezvuyCowZdo2ZLgX",
"title" : "Article title",
"intro" : "Some text",
"type" : "section",
}
{
"_id" : "eYkxs8rW3dKH5SfoE",
"title" : "element 1",
"order" : 1,
"type" : "element",
"parent" : "YezvuyCowZdo2ZLgX"
}
{
"_id" : "siaRPzaTgDrfWZ7kn",
"title" : "subelement 1",
"order" : 1,
"type" : "element",
"parent" : "ASkJZSkPAj8mhb7An"
}
{
"_id" : "DrfWZ7knsiaRPzaTg",
"title" : "subelement 2",
"order" : 2,
"type" : "element",
"parent" : "ASkJZSkPAj8mhb7An"
}
{
"_id" : "XZF9hpW8ZqTnRdkEg",
"title" : "element 2",
"order" : 3,
"type" : "element",
"parent" : "YezvuyCowZdo2ZLgX"
}
{
"_id" : "ASkJZSkPAj8mhb7An",
"title" : "group 1",
"type" : "group",
"parent" : "YezvuyCowZdo2ZLgX",
"order" : 2
}
您可以在页面上的任何位置订阅出版物,因此可以在创建或呈现时将订阅放在父模板中 您将
article.\u id
传递给您的子模板,然后在元素模板中使用该parentId
您知道文章模板中的文章。\u id,因此您可以在创建或呈现时订阅该模板中的子模板数据
如果这不是您正在做的,请澄清您的问题:在您的模板元素中
是嵌套在文章中的模板
如果您想要
元素的完整列表
,可以订阅此列表,您将获得所有元素
。然后集合已经加载,因此在文章
模板中查找单个元素
很便宜,因为它将仅在客户端上完成。好的,下表:
{
"_id" : "YezvuyCowZdo2ZLgX",
"title" : "Article title",
"intro" : "Some text",
"type" : "section",
}
{
"_id" : "eYkxs8rW3dKH5SfoE",
"title" : "element 1",
"order" : 1,
"type" : "element",
"immediateParent" : "YezvuyCowZdo2ZLgX",
"topLevelParent": "YezvuyCowZdo2ZLgX"
}
{
"_id" : "siaRPzaTgDrfWZ7kn",
"title" : "subelement 1",
"order" : 1,
"type" : "element",
"immediateParent" : "ASkJZSkPAj8mhb7An",
"topLevelParent": "YezvuyCowZdo2ZLgX"
}
{
"_id" : "DrfWZ7knsiaRPzaTg",
"title" : "subelement 2",
"order" : 2,
"type" : "element",
"immediateParent" : "ASkJZSkPAj8mhb7An",
"topLevelParent": "YezvuyCowZdo2ZLgX"
}
{
"_id" : "XZF9hpW8ZqTnRdkEg",
"title" : "element 2",
"order" : 3,
"type" : "element",
"immediateParent" : "YezvuyCowZdo2ZLgX",
"topLevelParent": "YezvuyCowZdo2ZLgX"
}
{
"_id" : "ASkJZSkPAj8mhb7An",
"title" : "group 1",
"type" : "group",
"order" : 2,
"immediateParent" : "YezvuyCowZdo2ZLgX",
"topLevelParent": "YezvuyCowZdo2ZLgX"
}
现在,每个文档都可以访问其顶级父元素。您的发布功能将是:
Meteor.publish( 'articles', function( articleId ) {
return Collection.find({ $or: [ {_id: articleId }, { topLevelParent: articleId }] };
});
而您的文章onCreated函数将如下所示:
Template.article.onCreated(function() {
var instance = this;
instance.autorun(function () {
var subscription = instance.subscribe('articles', Session.get('docId'));
});
instance.article = function() { return Collection.findOne({ _id: Session.get('docId') }); };
});
您的模板将稍作修改:
<template name="article">
{{#if Template.subscriptionsReady}}
<h1>{{article.title}}</h1>
<p>{{article.intro}}</p>
{{> elements articleId=article._id }}
{{else}}
<div class="loading">{{ > spinner }}</div>
{{/if}}
</template>
<template name="elements">
<ul>
{{#each elements articleId}}
<li>
<textarea>{{title}}</textarea>
{{> elements articleId=_id }}
</li
{{/each}}
</ul>
</template>
现在,您应该可以在一个发布和订阅中获得所需的所有数据。你的第二个问题:
var subscription = instance.subscribe('articles', Session.get('docId'), function() {
Meteor.setTimeout( function() { $('textarea').autosize(); }, 500); // Adjust down to a lower amount if possible.
});
希望能成功 但是我不能这样做,因为我在循环之前不知道元素的ID。编辑我的答案。或者你应该编辑你的问题,因为在我的理解中,你可以这样做。如果你需要帮助,不要否决那些试图回答你问题的人。我在问题中添加了数据结构。所以我认为我不能得到所有元素的完整列表,因为它们只是由父元素引用的…所以,在“部分”部分中有父元素ID。因此,在父模板中,您可以订阅具有该父模板的所有“元素”。不知道你为什么说不行。你试过用两个集合来代替吗?您可以存储主集合ID并使用该ID查找子集合&show微调器,直到主文档的订阅准备就绪,然后它可以显示子文档的微调器,直到它们准备就绪。您将进行两次发布/订阅,但这两次将分开。我不知道这是不是你想要的…听起来很棒。如何获得一个小函数,将toplevelparent信息添加到现有数据中?我想我必须对每个元素做一个each循环,对吗?是的,你需要循环每个项目,然后迭代该项目的父项,直到找到顶级项目,然后设置它。