我是Meteor的新手,想知道如何解决我认为常见的问题。
假设我有一个列出餐馆的把手模板:
<template name="Restaurants">
{{#each Restaurant}}
{{name}}
{{/each}}
</template>
现在,当用户点击餐馆模板时,我想显示该餐厅的菜单。
我添加了一个名为“menuItems”的子模板,其中包含给定餐厅的所有菜单项:
<template name="Restaurants">
{{#each Restaurant}}
{{name}}
{{> menuItems}}
{{/each}}
</template>
当用户点击餐厅模板上的任何位置时,我只想渲染一个menuItems子模板实例(仅渲染所选餐厅的菜单项)。
应该是这样的:
Template.Restaurants.events({
'click' : function (e) {
// This is where I need help - what's the right way to display only one subtemplate instance?
}
});
我的问题是 - 如何选择和显示正确的menuItems模板实例?
此外,我想将menuItems模板实例仅在点击之后放在DOM中,而不是之前(包含所有餐馆的所有菜单项,并且由于db中的这些项目数量很大,因此只能隐藏这些div)。
如果您认为我应该以其他方式处理解决方案,请告诉我,谢谢!
答案 0 :(得分:4)
您应该使用{{#if}}
和Session
。像这样:
<template name="Restaurants">
{{#each Restaurant}}
{{name}}
{{#if restaurantSelected}}
{{> menuItems}}
{{/if}}
{{/each}}
</template>
通过使用Session
,一个反应数据源,您可以设置一个全局标志,指示是否选择了一家餐馆。
Template.Restaurants.restaurantSelected = function() {
// check whether this restaurant is selected. "this" refers to the current
// context, eg. the current restaurant in the loop
return Session.equals("restaurantSelected", this._id);
}
每当您更改该会话密钥时,该值都将更新,并且将重新绘制模板。因此,您可以在点击餐厅时切换它:
Template.Restaurants.events({
'click' : function (e) {
// store the current restaurant ID
// make sure the event selector is correct!
Session.set("restaurantSelected", this._id);
}
});
修改为了清楚起见,我创建了a complete example,您可以将其复制到项目中并试用。
答案 1 :(得分:1)
我几乎总是避免使用Session。我认为它污染了全球范围。它还会阻止您运行模板的多个实例。我建议使用作为模板实例范围的reactiveVar或reactiveDict。感谢Rahul开始一个演示项目。我拿了他的例子并对其进行了修改以显示我推荐的方法。
将reactiveDict附加到模板实例onCreate上。使用它来存储状态而不是全局Session var!
Template.Restaurants.onCreated(function() {
this.state = new ReactiveDict;
this.state.set('currentRestaurant', null); // could set a init value here
});
此事件处理程序将在click
上设置reactiveDict的状态'click': function(e, t) {
t.state.set('currentRestaurant', this._id);
}
此助手用于显示/隐藏菜单模板
currentRestaurant: function() {
// check whether this restaurant is selected. "this" refers to the current
// context, eg. the current restaurant in the loop
return Template.instance().state.equals("currentRestaurant", this._id);
},
菜单模板从数据上下文而不是从Session
接收所选的id<template name="Restaurants">
<ul>
{{#each Restaurant}}
<li>
{{name}}
{{#if currentRestaurant}}
{{> menuItems restaurant=_id}}
{{/if}}
</li>
{{/each}}
</ul>
</template>
<template name="menuItems">
<ul>
<li class="menu">I'm a menu for {{restaurantName}}!</li>
</ul>
</template>
添加此帮助器只是为了表明我们确实得到了id
Template.menuItems.helpers({
restaurantName: function() {
var restaurantMenu = Restaurants.findOne(this.restaurant);
return restaurantMenu.name;
},
})
向github发布了一个完全正常工作的项目。 https://github.com/white-rabbit-japan/scopedReactivityDemo
应用程序托管在meteor.com上 http://scopedreactitivydemo.meteor.com/