从模板事件回调中调用模板辅助函数

calling a template helper function from inside a template event callback

我对 meteor 很陌生,我可能完全错误地处理了这个问题。

我有一个代表菜单栏的简单模板。当用户单击图标时,应该会出现菜单。当他们再次点击它时,它应该会消失。

这是标记:

<template name="menu">
  <div class="menu">
    <div class="toggler">
      <i class="fa fa-bars fa-3x"></i>
    </div>
    <div class="menu-body">
       <!-- ... -->
    </div>
  </div>
</template>

这是我拥有的 JS:

Template.menu.helpers({
    self: Template.instance(),
    menu_body: self.find('.menu-body'),
    toggler: self.find('.toggler'),

    currently_open: false,
    open: function() {
        menu_body.style.display = 'flex';
    },
    close: function() {
        menu_body.style.display = 'none';
    },
    toggle: function() {
        if(currently_open) close();
        else open();
    }
});

Template.menu.events({
    'click .toggler': function(event, template) {
        console.log(template);
        template.toggle();
    }
});

我以为模板实例可以访问辅助函数,但根据日志语句,模板实例的组成如下:

B…e.TemplateInstance {view: B…e.View, data: null, firstNode: div.menu, lastNode: div.menu, _allSubsReadyDep: T…r.Dependency…}
  _allSubsReady: false
  _allSubsReadyDep: Tracker.Dependency
  _subscriptionHandles: Object
  data: null
  firstNode: div.menu
  lastNode: div.menu
  view: Blaze.View
  __proto__: Blaze.TemplateInstance

有人可以在这里为我指明正确的方向吗?如果我做错了,请随时仔细检查。

助手用于功能调用 - 不是事件驱动的作品。

Meteor 有一个事件句柄,您可以使用它来跟踪点击等事件。您也可以使用 css classes 很好地定义样式,而无需以编程方式覆盖它们。

Template.name.events({
'click .menuToggler': function(event, template) {
  event.preventDefault();
  var menu = template.find('.menu-body'); //(make this in ID!)
  if($(menu).hasClass('menuOpen')) {
     $(menu).removeClass('menuOpen');
     //menu.style.display = 'none';
  } else {
     $(menu).addClass('menuOpen');
     //menu.style.display = 'flex'; Use css to define these on the menuOpen class
  }
});

一些注意事项:此事件句柄假定您的菜单正文 class 在我的示例中名为 "name" 的模板下可用。所以你会希望这个事件处理程序位于你拥有的最顶层模板中。它还假设。

如果您想在模板的各个组件(助手、事件回调等)之间共享状态,应该通过直接在模板实例上设置属性来完成。

这可以通过 onCreated() 回调

根据文档:

Callbacks added with this method [are] called before your template's logic is evaluated for the first time. Inside a callback, this is the new template instance object. Properties you set on this object will be visible from the callbacks added with onRendered and onDestroyed methods and from event handlers.

These callbacks fire once and are the first group of callbacks to fire. Handling the created event is a useful way to set up values on template instance that are read from template helpers using Template.instance().

因此,提供一个比我原来的问题中的例子更相关、更简洁的例子。

Template.menu.onCreated(function() {
  this.items =  [
    {title: 'Home',    icon: 'home'},
    {title: 'Profile', icon: 'user'},
    {title: 'Work',    icon: 'line-chart'},
    {title: 'Contact', icon: 'phone'}
  ];
});

Template.menu.helpers({
  items: function() {
    var self = Template.instance();
    return self.items;
  }
});

Template.menu.events({
  'click .toggler': function(event, template) {
    console.log(template.items); //[Object,Object,Object,Object]
    //do something with items
  }
});

这真的很有趣,但我创建了一个迷你包来帮助您做到这一点:https://atmospherejs.com/voidale/helpers-everywhere

但在你的情况下,这不是正确的做法。我可以看到你想添加一个显示 flexnone 最好添加 CSS 元素,如 active 保持 display: flex 并添加 active 或者像这样点击删除它:$('').addClass('active') or $().removeClass('active')

一个班轮也可以在这里工作:$('.menu-body').toggleClass('active')