流星中的模板重用

时间:2012-12-31 07:14:07

标签: meteor handlebars.js

我正在尝试在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>

editingSession布尔值。

连接控件以显示,隐藏和“提交”表单的好方法是什么?

2 个答案:

答案 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了解模板实例。