问题
I'm having a little trouble returning and displaying tags that I'm adding to a subdocument. I have no problem adding tags, but want to put a label on the item for each tag. I simply can't find a resource that helps me return the items in an array within a subdocument. I think it's all the helper where I'm stuck - basically the syntactically correct way to write "Items.(this._id).itemTags.find();" :)
Oh - and I've cut out a lot of the HTML and JS, but, yes, everything else is working fine. The collection is "Items" and the subdocument is "itemTags", set with "itemTags: []" during the insert. In my test environment I can add "Cats" and "Dogs" as tags and can verify it works by inspecting the objects through "Items.find().fetch();" but am struggling to display them.
HTML:
<template name="item">
{{#each itemTags}}
<span class="label label-default">{{itemTag}}</span>
{{/each}}
</template>
JS:
Template.item.helpers({
itemTags: function() {
var currentUserId = Meteor.userId();
return Items.find(); // yes, this line is completely wrong, but I'm lost hehe
}
});
Template.item.events({
'submit .add-tag': function(event) {
event.preventDefault();
var itemTag = event.target.text.value;
Items.update(this._id, {$push: {itemTags: itemTag}});
event.target.text.value = "";
return false;
}
});
Database schema (as shown by my insert command):
var item = {
itemText: $(e.target).find('[name=itemText]').val(),
createdAt: new Date(),
createdBy: currentUserId,
hard: false,
difficulty: 'easy',
checked: false,
itemTags: [],
};
item._id = Items.insert(item);
回答1:
Your only problem is trying to iterate a cursor and a sub array within the same each block. If you separate your items
template and an individual item
template, you'll end up with your desired result.
For the sake of simplification, I altered your code to look like this:
This is your main body:
<body>
{{> items}}
</body>
<template name="items">
{{#each items}}
{{> item}}
{{/each}}
</template>
<template name="item">
<h2>{{itemText}} tags are:</h2>
<ul>
{{#each itemTags}}
<li>{{this}}</li>
{{/each}}
</ul>
</template>
And this is your helper:
Template.items.helpers({
items: function () {
return Items.find();
}
})
Assuming an item document looks like:
{
itemText: String,
itemTags: Array
}
I've created an app on Meteorpad for you to play with:
http://meteorpad.com/pad/BmRQ5fkwWEMBKszJW/SO-27951102
you can further alter the code there and see the changes in realtime. It is basically jsfiddle for meteor.
Edit:
inspired by @chip-castle's comment, you can in fact use a single template with nested each
blocks:
<template name="items">
{{#each items}}
<h2>{{itemText}} tags are:</h2>
<ul>
{{#each itemTags}}
<li>{{this}}</li>
{{/each}}
</ul>
{{/each}}
</template>
But using separate templates is more flexible in both design and handling events where necessary.
回答2:
Do you have a publication and subscription setup?
server/publications.js
Items = new Mongo.Collection("items");
Meteor.publish("items", function () {
return Items.find({});
});
client/subscriptions.js
Items = new Mongo.Collection("items");
Meteor.subscribe("items");
来源:https://stackoverflow.com/questions/27951102/returning-subdocument-array-through-meteor-mongo