Meteor覆盖包中元素的click事件

时间:2015-06-27 11:53:55

标签: javascript meteor meteor-autoform

我正在尝试覆盖autoform-remove-item按钮的按钮单击事件,如下所示,因为我试图显示一条警告消息(之前),用户可以删除Autoform数组中的任何项目。然后,如果用户确认删除了项目,则按钮点击事件将继续正常。但是,在用户确认/拒绝删除之前,我无法弄清楚如何覆盖按钮的点击事件以暂停其下方的代码(我无权访问)?有什么帮助我可能会在这里失踪吗?感谢

    Template.salesInvoice.events({
       'click .autoform-remove-item': function(e){

            e.preventDefault();

            bootbox.dialog({
              message: "Are you sure you wish to delete this item?",
              title: "New Journal",
              buttons: {
                eraseRecord: {
                  label: "Yes!",
                  className: "btn-danger",
                  callback: function() {

                  }
                },
                doNotEraseRecord: {
                  label: "No!",
                  className: "btn-primary",
                  callback: function() {
                    //Continue with the normal button click event                

                  }
                }

              }
            });
       }

    });

我试图覆盖的点击事件:

      'click .autoform-remove-item': function autoFormClickRemoveItem(event, template) {
        var self = this; // This type of button must be used within an afEachArrayItem block, so we know the context

        event.preventDefault();

        var name = self.arrayFieldName;
        var minCount = self.minCount; // optional, overrides schema
        var maxCount = self.maxCount; // optional, overrides schema
        var index = self.index;
        var data = template.data;
        var formId = data && data.id;
        var ss = AutoForm.getFormSchema(formId);

        // remove the item we clicked
        arrayTracker.removeFromFieldAtIndex(formId, name, index, ss, minCount, maxCount);
      },

3 个答案:

答案 0 :(得分:6)

在圈子里跑了一个小时后,这就是我发现的。 Blaze在templateInstance的父元素的内侧安装它的事件监听器。他们被存放的财产称为$blaze_events。它易于使用,但没有文档记录。以下是您可以使用它的方法:

检索事件处理程序

处理程序存储在数组($blaze_events.handlers)中。所以为了找到一个特定的,我写了这个函数:

retrieveBlazeEvent = function retrieveBlazeEvent (parentElement, eventType, selector) {
  var returnHandler
  parentElement.$blaze_events[eventType].handlers.forEach(function (eventHandler) {
    if(eventHandler.selector === selector)
      return (returnHandler = eventHandler) && false
  })
  return returnHandler
}

用法:

的客户机/的test.html

<template name="test">
  <p>Hi!</p>
</template>

的客户机/ main.html中

{{&gt;测试}}

的客户机/ main.js

Template.test.events({
  'click p': function () {
    console.log('PIII')
  }
})

retrieveBlazeEvent(document.body, 'click', 'p')

删除事件侦听器

retrieveBlazeEvent返回的事件处理程序具有函数unbind。所以这是一个例子

retrieveBlazeEvent(document.body, 'click', 'p').unbind()

调用此函数后,事件处理程序仍然存在。要恢复它,您只需在同一个对象上调用bind即可。

手动触发事件处理程序

假设我们有一个简单的p - 元素。正在收听点击事件:

Template.test.events({
  'click p': function () {
    console.log('PIII')
  }
})

要触发事件处理程序,我们需要一个与此选择器匹配的p元素。我们还需要模板实例来检索正确的父节点。然后我们需要以视图作为其上下文来调用事件处理程序。我们还需要为包含currentTarget的事件绑定创建存根。这个功能可以满足您的所有需求:

triggerEvent = function triggerEvent (eventType, elementSelector, context) {
  var context = context || document
  var element = context.querySelector(elementSelector)
  var eventStub = {
    currentTarget: element
  }
  var view = Blaze.getView(element)
  retrieveBlazeEvent(view._domrange.parentElement, eventType, elementSelector)
    .delegatedHandler
    .call(view, eventStub)
  return true
}

答案 1 :(得分:2)

您是否只能在删除集合的代码中显示bootbox确认?然后仅在用户确认时将其从集合中删除。例如,我认为这应该有所帮助:

  'click .autoform-remove-item': function autoFormClickRemoveItem(event, template) {
        bootbox.dialog({
          message: "Are you sure you wish to delete this item?",
          title: "New Journal",
          buttons: {
            eraseRecord: {
              label: "Yes!",
              className: "btn-danger",
              callback: function() {
                  var self = this;
                  var name = self.arrayFieldName;
                  var minCount = self.minCount; // optional, overrides schema
                  var maxCount = self.maxCount; // optional, overrides schema
                  var index = self.index;
                  var data = template.data;
                  var formId = data && data.id;
                  var ss = AutoForm.getFormSchema(formId);
                  arrayTracker.removeFromFieldAtIndex(formId, name, index, ss, minCount, maxCount);
              }
            },
            doNotEraseRecord: {
              label: "No!",
              className: "btn-primary",
              callback: function() {
                //Continue with the normal button click event                

              }
            }

          }
        });
   }
  }

答案 2 :(得分:1)

您可以使用stopPropagation来阻止事件冒泡到autoform挂钩。

所以简短版本:

Template.afArrayField.events({
  'click .autoform-remove-item': function(event) {
      if (!confirm('Are you sure you wish to delete this item?')) {
          event.stopPropagation()
      }
  }
})