简体   繁体   English

从模板事件回调内部调用模板帮助器函数

[英]calling a template helper function from inside a template event callback

I am very new to meteor and it is possible that I am going about this entirely incorrectly. 我对流星很陌生,可能我完全不正确地进行了处理。

I have a simple template that represents a menu bar. 我有一个代表菜单栏的简单模板。 When the user clicks an Icon, the menu is supposed to appear. 当用户单击图标时,菜单应该会出现。 When they click it again, it is supposed to disappear. 当他们再次单击它时,它应该消失了。

Here is the markup: 这是标记:

<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>

Here is the JS that I have: 这是我拥有的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();
    }
});

I thought the template instance would have access to the helper functions, but according to the log statement, this is what the template instance consists of: 我以为模板实例可以访问辅助函数,但是根据log语句,这是模板实例的组成部分:

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

Can someone point me in the right direction here. 有人可以在这里指出我正确的方向。 Please feel free to be scrutinous if I am going about it wrong. 如果我做错了,请随时进行仔细检查。

Helpers are for functional calls - not event driven works. 助手用于功能调用-不是事件驱动的作品。

Meteor has an events handle that you can use to track events like clicks. 流星具有事件句柄,可用于跟踪诸如点击之类的事件。 Also you can use your css classes to define the styles nicely without programatically overwriting them. 您也可以使用CSS类很好地定义样式,而无需以编程方式覆盖它们。

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
  }
});

Some things to note: This event handle assumes that your menu-body class is available under the template called "name" in my example. 注意事项:此事件句柄假定您的菜单主体类在本例中的“名称”模板下可用。 So you will want this event handler at the most top level template you have. 因此,您将希望此事件处理程序位于您拥有的最高级模板中。 It also assumes. 它也假设。

If you want to share state between the various components of your template (helpers, event callbacks etc) it should be done by setting properties directly on the template instances. 如果要在模板的各个组件(助手,事件回调等)之间共享状态,则应通过直接在模板实例上设置属性来完成。

This can be done through the onCreated() callback 这可以通过onCreated()回调来完成

As per the documentation: 根据文档:

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. 在回调内部, this是新的模板实例对象。 Properties you set on this object will be visible from the callbacks added with onRendered and onDestroyed methods and from event handlers. 您在此对象上设置的属性将从通过onRendered和onDestroyed方法添加的回调以及事件处理程序中可见。

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.instance()从模板助手中读取的。

So, to provide a more relevant and concise example than the one in my original question. 因此,提供一个比我原始问题中的示例更为相关和简洁的示例。

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
  }
});

That's actually funny but I created a mini package that helps you do just that: https://atmospherejs.com/voidale/helpers-everywhere 这实际上很有趣,但是我创建了一个迷你包来帮助您做到这一点: https : //atmospherejs.com/voidale/helpers-everywhere

But in your case it's not the right way of doing it. 但是对于您而言,这不是正确的方法。 I can you see you want to add an display either flex or none it's better add CSS element like active that hold display: flex and add active or remove it on click like this: $('').addClass('active') or $().removeClass('active') 我可以看到你想要添加的显示器无论是flexnone ,最好添加CSS元素一样active持有display: flex ,并添加active或删除其上点击这样的: $('').addClass('active') or $().removeClass('active')

one liner can also work here: $('.menu-body').toggleClass('active') 一个班轮也可以在这里工作: $('.menu-body').toggleClass('active')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM