为什么我的模板不是if条款更新被动?

时间:2015-12-08 08:21:57

标签: javascript meteor helpers spacebars

无论出于何种原因,我都无法通过无数小时的故障排除来解决这个问题。我有一些使用Bootstrap 3 nav-tabs列表的简单助手。

我想基于哪个列表项处于活动状态来呈现不同的模板。这是我的助手:

Template.Profile.helpers({
  'personal':function(){
    if($('.profile-info').hasClass('active')) {
      return true;
    } else {
      return false;
    }
  },
  'groups':function(){
    if($('.profile-groups').hasClass('active')) {
      return true;
    } else {
      return false;
    }
  },
  'commitments':function(){
    if($('.profile-commitments').hasClass('active')) {
      return true;
    } else {
      return false;
    }
  }
});

这是我的HTML:

<ul class="nav nav-tabs">
    <li class="active profile-info"><a href="#">Personal Info</a></li>
    <li class="profile-groups"><a href="#">Groups</a></li>
    <li class="profile-commitments"><a href="#">Commitments</a></li>
</ul>

{{#if personal}}
    {{> ProfilePersonal}}
{{else}}
    {{#if groups}}
        {{> ProfileGroups}}
    {{else}}
        {{> ProfileCommits}}
    {{/if}}
{{/if}}

1 个答案:

答案 0 :(得分:1)

单击选项卡时不会重新运行帮助程序,因为没有反应数据更改以使计算无效。

更多Meteor-ish方法是添加一个反应变量来保存选项卡状态并在事件监听器中更改它。

<template name="Profile">
  <ul class="nav nav-tabs">
  {{#each tabs}}
    <li class="{{isActive @index}} profile-{{name}}"><a href="#">{{title}}</a></li>
  {{/each}}
  </ul>
  {{> Template.dynamic template=tpl}}
</template>

@index引用当前循环的索引,并将其作为isActive帮助程序的参数提供。

然后,您的JavaScript文件可以包含选项卡和处理代码的定义:

var tabs = [{
  idx: 0,
  name: "info",
  title: "Personal Info",
  template: "ProfilePersonal"
}, {
  idx: 1,
  name: "groups",
  title: "Groups",
  template: "ProfileGroups"
}, {
  idx: 2,
  name: "commitments",
  title: "Commitments",
  template: "ProfileCommits"
}];

标签是一个普通的JS数组。以下代码在模板的上下文中使用它们:

Template.Profile.helpers({
  // get current sub-template name
  tpl: function() {
    var tpl = Template.instance();
    return tabs[tpl.tabIdx.get()].template;
  },
  // get the tabs array
  tabs: function() {
    return tabs;
  },
  // compare the active tab index to the current index in the #each loop.
  isActive: function(idx) {
    var tpl = Template.instance();
    return tpl.tabIdx.get() === idx ? "active" : "";
  }
});

Template.Profile.events({
  'click .nav-tabs > li': function(e, tpl) {
    tpl.tabIdx.set(this.idx);
  }
});

Template.Profile.onCreated(function() {
  this.tabIdx = new ReactiveVar();
  this.tabIdx.set(0);
});

创建模板(onCreated())时,会添加一个新的反应变量作为实例变量。然后可以在助手中访问此变量并在事件处理程序中设置。

事件处理程序接收事件对象和模板实例作为参数,并将数据上下文设置为this指针;因此,tpl.tabIdx表示反应变量,this表示表示单击选项卡的对象(例如,

{
  idx: 0,
  name: "info",
  title: "Personal Info",
  template: "ProfilePersonal"
}
第一个选项卡的

,因为这是第一个选项卡呈现时模板的数据上下文。

帮助函数使用对Template的调用获取Template.instance()实例。然后,它查询反应数组的值。

这会在反应式上下文中创建计算(帮助程序是反应式上下文,当它们创建的计算失效时会重新运行,并且当Mongo游标或计算中读取的反应变量发生更改时会发生这种情况。

因此,当在事件处理程序中设置反应变量时,将重新运行帮助程序,模板将反映新值。

这些都是Meteor的基础,并在完整的Meteor文档和许多资源中进行了解释。