【问题标题】:calling a template helper function from inside a template event callback从模板事件回调内部调用模板帮助函数
【发布时间】:2015-07-10 00:52:55
【问题描述】:

我对流星很陌生,我可能完全不正确地处理这个问题。

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

这里是标记:

<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

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

【问题讨论】:

    标签: javascript templates meteor meteor-blaze


    【解决方案1】:

    Helper 用于功能调用 - 不是事件驱动的工作。

    Meteor 有一个事件句柄,您可以使用它来跟踪点击等事件。您还可以使用您的 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
      }
    });
    

    需要注意的事项:此事件句柄假定您的 menu-body 类在我的示例中名为“name”的模板下可用。因此,您将希望此事件处理程序位于您拥有的最顶层模板中。它也假设。

    【讨论】:

      【解决方案2】:

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

      这可以通过onCreated() 回调来完成

      根据文档:

      使用此方法添加的回调 [被] 在模板逻辑之前调用 第一次被评估。在回调中,this 是新的 模板实例对象。您在此对象上设置的属性将是 从使用 onRendered 和 onDestroyed 添加的回调中可见 方法和事件处理程序。

      这些回调触发一次并且是第一组回调 火。处理 created 事件是设置值的有用方法 从模板助手读取的模板实例使用 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
        }
      });
      

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

          猜你喜欢
          • 2016-05-21
          • 2015-09-14
          • 2012-05-21
          • 2015-05-09
          • 1970-01-01
          • 2022-08-05
          • 1970-01-01
          • 1970-01-01
          • 2016-05-26
          相关资源
          最近更新 更多