我正在尝试在Meteor应用中重用一些控制元素。我想要以下两个模板来切换不同表单的可见性和提交。
<template name='addControl'>
<img class='add' src='/images/icon-plus.png' />
</template>
<template name='okCancelControl'>
<img class='submit' src='/images/icon-submit.png' />
<img class='cancel' src='/images/icon-cancel.png' />
</template>
我会在另一个模板中调用这些模板:
<template name='insectForm'>
{{#if editing}}
<!-- form elements -->
{{> okCancelControl}}
{{else}}
{{> addControl}}
{{/if}}
</template>
editing
是Session
布尔值。
连接控件以显示,隐藏和“提交”表单的好方法是什么?
答案 0 :(得分:2)
主要问题是从控件模板中找到addInsect模板(数据所在的位置)(“submit”事件触发的位置)。这是我做的:
首先,控件:
<template name='addControl'>
<section class='controls'>
<span class="add icon-plus"></span>
</section>
</template>
<template name='okCancelControl'>
<section class='controls'>
<span class="submit icon-publish"></span>
<span class="cancel icon-cancel"></span>
</section>
</template>
现在是javascripts。他们只需在点击时调用回调。
Template.addControl.events({
'click .add': function(event, template) {
if (this.add != null) {
this.add(event, template);
}
}
});
Template.okCancelControl.events({
'click .cancel': function(event, template) {
if (this.cancel != null) {
this.cancel(event, template);
}
},
'click .submit': function(event, template) {
if (this.submit != null) {
this.submit(event, template);
}
}
});
然后我使用把手'#with
块助手连接了回调。
<template name='addInsect'>
{{#with controlCallbacks}}
{{#if addingInsect}}
<section class='form'>
{{> insectErrors}}
<label for='scientificName'>Scientific Name <input type='text' id='scientificName' /></label>
<label for='commonName'>Common Name <input type='text' id='commonName' /></label>
{{> okCancelControl}}
</section>
{{else}}
{{> addControl}}
{{/if}}
{{/with}}
</template>
创建与此表单相关的回调的相应javascript。
Session.set('addingInsect', false);
Template.addInsect.controlCallbacks = {
add: function() {
Session.set('addingInsect', true);
Session.set('addInsectErrors', null);
},
cancel: function() {
Session.set('addingInsect', false);
Session.set('addInsectErrors', null);
},
submit: function() {
var attrs, errors;
attrs = {
commonName: DomUtils.find(document, 'input#commonName').value,
scientificName: DomUtils.find(document, 'input#scientificName').value
};
errors = Insects.validate(attrs);
Session.set('addInsectErrors', errors);
if (errors == null) {
Session.set('addingInsect', false);
Meteor.call('newInsect', attrs);
}
}
};
Template.addInsect.addingInsect = function() {
Session.get('addingInsect');
};
Template.addInsect.events = {
'keyup #scientificName, keyup #commonName': function(event, template) {
if (event.which === 13) {
this.submit();
}
}
};
在提交回调中,我必须使用DomUtils.find
而不是template.find
,因为template
是okCancelControl的实例,而不是addInsect。
答案 1 :(得分:1)
您可以使用Session
。您只需要一个模板助手,它返回一个boolean
标志,指示您是否正在编辑表单字段。并根据此模板助手设置的Session值操作DOM。
假设您有一个文本输入,现在当您在其中输入文本时,将会话标记设置为true
。这将触发帮助程序返回true flag
,基于此,您的两个模板中的一个将在DOM中呈现。
isEditing
是每当您更改会话值时触发的帮助程序。
这个辅助函数是这里的主要部分,它根据你设置的会话值返回true / false。
Template.insectForm.isEditing = function(){
if(Session.get('isEditing')){
return true;
}
else{
return false;
}
}
请务必在启动时将会话设置为false
:
$(document).ready(function(){
Session.set('isEditing', false);
})
这将在html中呈现默认的add template
,现在当您点击ADD时,您需要显示另一个模板,为此,将Session设置为true为:
'click .add' : function(){
Session.set('isEditing', true);
}
因此,当您点击取消时,将会话设置为false
,这将使isEditing
返回false
,并显示默认的add template
。
所以你的完整html看起来像这样:
<template name='insectForm'>
{{#if isEditing}}
<!-- form elements -->
<input type="text" id="text" value="">
{{> okCancelControl}}
{{else}}
{{> addControl}}
{{/if}}
</template>
<template name='addControl'>
<img class='add' src='/images/icon-plus.png' />
</template>
<template name='okCancelControl'>
<img class='submit' src='/images/icon-submit.png' />
<img class='cancel' src='/images/icon-cancel.png' />
</template>
<强> [UPDATE] 强>
要获取模板的实例,您需要在表示模板的事件处理程序中传递其他参数。
因此请将您的事件处理程序更新为:
Template.insectForm.events = {
'click .submit' : function(event, template){
//your event handling code
}
}
参数template
是事件源自的模板的实例。
请注意,虽然事件触发形成okCancelControl
模板内的图像,但该参数仍将包含insectForm
模板的实例。这是因为我们将事件处理程序称为Template.insectForm.events = {}
。
另请参阅this answer了解模板实例。