Meteor:每个模板是否有一个反应范围?
我在同一页面的多个(任意多个)位置呈现相同的把手模板。在每个模板中,我需要一个按钮来切换div的可见性。当我使用Meteor:每个模板是否有一个反应范围?,meteor,handlebars.js,Meteor,Handlebars.js,我在同一页面的多个(任意多个)位置呈现相同的把手模板。在每个模板中,我需要一个按钮来切换div的可见性。当我使用Session.set保存此状态时,单击一个按钮显然会切换所有模板实例化中不需要的所有div 我可以将状态保存在模板实例的数据上下文中(该实例绑定到template.myTemplate.rendered和template.myTemplate.created回调中的this.data),但存在两个问题 this.data不是被动数据源,因此不会传播到div 我无权访问template
Session.set
保存此状态时,单击一个按钮显然会切换所有模板实例化中不需要的所有div
我可以将状态保存在模板实例的数据上下文中(该实例绑定到template.myTemplate.rendered
和template.myTemplate.created
回调中的this.data
),但存在两个问题
this.data
不是被动数据源,因此不会传播到divtemplate.myTemplate.events
中的模板实例(如上所述)$scope
更新:
我在想这样的事情
template.html:
<template name="jsonObject">
<input type="button" />
<div class="{{hidden}}">content</div>
</template>
我认为关于流星核心的讨论已经过时(尽管是最近的)。(以下引用),这应该是可能的:
Template.myTemplate.events({
foo: function(event, template) {
var _div = template.find('...');
}
});
handler函数接收两个参数:event,一个包含事件信息的对象;template,一个定义处理程序的模板实例。根据处理事件的当前元素的上下文,处理程序还接收一些额外的上下文数据。在Handlebars模板中,元素的上下文是该元素所在的Handlebars数据上下文,由块帮助器(如#with和#each)设置
更新
假设每个可隐藏的div都有一个唯一的id,那么如果您尝试这样的方法呢?我还没有测试过
Template.jsonObject.hidden = function(){
var _id = $(".classOfPossibleHiddenDiv").prop("id");
return Session.get(_id) || false;
};
Template.jsonObject.events({
'click input' : function(event, template){
Session.set($(template.find(".classOfPossibleHiddenDiv")).prop("id"), true);
}
});
这就是我如何实现每个模板实例反应源的方法 我只想问用户当恐龙的灭绝状态设置为灭绝时,恐龙灭绝的原因
<template name="dinosaur">
<label for="extinction-status">Extinction status</label>
<select name="extinction-status">
<option value="not-extinct">Not extinct</option>
<option value="extinct">Extinct</option>
</select>
{{#if isExtinct extinctStatus newExtinctStatus extinctStatusDep}}
<label for="extinction-reason">Reason for extinction</label>
<input name="extinction-reason" type="text" placeholder="Why is it extinct?"/>
{{/if}}
</template>
我们监听用户何时更改熄灭状态选择,并更新新熄灭状态
,并在熄灭状态下调用已更改
Template.dinosaur.events({
'change [name="extinction-status"]': function(event, template) {
var extinctStatus = $(event.target).val();
template.data.newExtinctStatus = extinctStatus;
template.data.extinctStatusDep.changed();
}
});
在helper中,我们说我们依赖于Deps.Dependency
传递
Template.dinosaur.helpers({
isExtinct: function(status, newStatus, statusDep) {
if (statusDep) {
statusDep.depend();
}
if (newStatus) {
if (newStatus == 'extinct') {
return true;
}
else if (status == 'extinct') {
// No new status is set, so use the original.
return true;
}
}
});
添加到此.data
有点像黑客,但它允许每个模板的反应性,在依赖尚未保存到集合中的数据时非常有用。更新的答案-METEOR 0.8.3
Meteor现在提供了UI.\u templateInstance()
函数,该函数允许在模板帮助程序中访问模板实例。这使得实现更加简洁:
一,。
在下面的HTML代码中,删除{{#with templateInstanceId=getTemplateInstanceId}
二,。
用以下代码替换JS代码:
var templateInstanceId = 0;
Template.divWithToggleButton.created= function()
{
this.templateInstanceId = ++templateInstanceId;
};
Template.divWithToggleButton.events(
{
'click button': function(event, template)
{
Session.set("visible", template.templateInstanceId);
},
});
Template.divWithToggleButton.visible= function()
{
return Session.equals("visible", UI._templateInstance().templateInstanceId);
};
以前的答案
我在我的项目中也有同样的要求:唯一地标识一个模板实例,以便与Session.set一起使用
下面是我的简单技巧,使用上下文替换和“滑动”唯一实例id(稍后将对此进行详细介绍):
在客户端代码中的任意位置,放置:
var templateInstanceId = 0;
UI.registerHelper('getTemplateInstanceId', function()
{
return templateInstanceId++;
});
然后在要唯一标识实例的模板中使用{{#with templateInstanceId=getTemplateInstanceId}
。以您的示例为例,可能是这样的(未经测试):
HTML:
关于这个奇怪的“滑动”唯一实例id:
这个id在每次模板渲染时都会更新,我没有找到其他方法。这意味着任何新的呈现都将使存储在会话中的唯一id无效。如果div包含反应式数据源,则会发生新的呈现。根据您的情况,这可能是个问题,也可能不是。所有其他答案都太复杂和/或过时。从Meteor 1.0开始,维护每个模板状态的建议解决方案是使用存储在:
模板实例对象表示文档中模板的引用。它可以用来访问DOM,并且可以为其分配属性,这些属性会随着模板的反应性更新而保持不变。[…]您可以将自己选择的其他属性指定给对象
反应变量由以下程序提供:
一个ReactiveVar持有一个可以获取和设置的值,这样调用set
将使调用get
的任何计算无效,这与反应式数据源的通常约定是一致的
您的代码变成:
Template.jsonObject.onCreated=函数(){
this.hidden=新的反应变量(false);
};
Template.jsonObject.helpers({
隐藏:函数(){
返回Template.instance().hidden.get()?“hidden”:“”;
}
});
Template.jsonObject.events({
“单击输入”:函数(事件、模板){
template.hidden.set(true);
}
});
HTML与您预期的相同:
点击我
隐藏是{{Hidden}
谢谢,但这仍然存在一个问题,即template.data不是被动的。对。这是有道理的。我更新了我的答案。这可能有点黑客。加上一个黑客解决方案:)我想如果我有一个全局计数器来生成它工作的ID,.下划线有一个漂亮的。.uniqueId
函数,可能很有用。有一个.聪明的。我将其简化为动画系统,但您所建议的核心工作得非常好,即将依赖项作为this.data.Great问题的属性。我在AngularJS中缺少此功能。从Meteor 0.9.1开始,UI.\u templateInstance
已重命名为Template.instance
。事情是这样的
var templateInstanceId = 0;
Template.divWithToggleButton.created= function()
{
this.templateInstanceId = ++templateInstanceId;
};
Template.divWithToggleButton.events(
{
'click button': function(event, template)
{
Session.set("visible", template.templateInstanceId);
},
});
Template.divWithToggleButton.visible= function()
{
return Session.equals("visible", UI._templateInstance().templateInstanceId);
};
var templateInstanceId = 0;
UI.registerHelper('getTemplateInstanceId', function()
{
return templateInstanceId++;
});
<!-- Div with a toggle visibility button. Use as a Block Helpers (with # instead of >) -->
<template name="divWithToggleButton">
{{#with templateInstanceId=getTemplateInstanceId }}
<div>
<!-- The 'toggle visibility' button -->
<button type="button">Toggle Visibility</button>
<!-- The div content -->
{{#if visible}}
{{> UI.contentBlock}}
{{/if}}
</div>
{{/with}}
</template>
Template.divWithToggleButton.events(
{
'click button': function(event, template)
{
Session.set("visible", this.templateInstanceId);
},
});
Template.divWithToggleButton.visible= function()
{
return Session.equals("visible", this.templateInstanceId);
};