如何在流星中使用回调?

时间:2012-10-28 21:02:46

标签: meteor

我已经创建了一个帮助器,用于在我的Meteor应用程序中显示通用模态(在coffeescript中)。

这是modal.coffee:

showModal = (modalType, title, body, callback) ->
  validModals = [ "Error", "YesNo" ]

  if not modalType in validModals
    alert "Invalid modal type specified"    # @todo - find a better way of handling this error

  Session.set "modalType", modalType
  Session.set "modalTitle", title or ""
  Session.set "modalBody", body or ""
  modalCallback = callback or undefined
  Session.set "showModal", true

Template.modal.title = () ->
  Session.get "modalTitle"

Template.modal.body = () ->
  Session.get "modalBody"

Template.modal.response = () ->
  switch Session.get "modalType" 
    when "Error"
      [{
        css: 'cancel',
        message: 'OK'
      }]
    when "YesNo"
      [
        {
          css: 'cancel',
          message: "No"
        },
        {
          css: 'btn-primary',
          message: "Yes"
        },
      ]

Template.page.shouldShowModal = () ->
  Session.get "showModal"

Template.modal.events {
  'click .cancel': ->  
    Session.set "showModal", false
    cb = modalCallback
    alert "here " + cb
    if cb
      cb(false)
  'click .btn-primary': ->
    Session.set "showModal", false
    cb = Session.get "modalCallback"
    if cb
      cb(true)
}

模板很无聊。

这是我的客户端代码(如此助手的调用者):

Template.details.events {
  'click .remove': () ->
    showModal "YesNo", 
      "Are you sure you want to delete this item?", 
      "Deleting an items can't be undone. Are you sure you want to delete?", 
      (response) =>
        if response
          Items.remove this._id, (err) =>
            if err
              showModal "Error", "Error removing item", err.reason

    return false;
}

我无法让它执行回调。我看到的所有示例最终都将所有内容都放入会话中,但显然它无法将函数转换为json,因此当用户单击ok或取消按钮时,它不会正确反序列化。

当用户响应我的模态时,如何执行回调?

2 个答案:

答案 0 :(得分:2)

缔约方的例子展示了我喜欢的另一种模式。使用会话变量来显示/隐藏对话框/模态,并将回调放在Template事件处理程序中。

例如,请在此处查看inviteDialog模板: https://github.com/meteor/meteor/blob/master/examples/parties/client/parties.html#L194

此会话变量控制其可见性: https://github.com/meteor/meteor/blob/master/examples/parties/client/parties.html#L15

这是一个回调: https://github.com/meteor/meteor/blob/master/examples/parties/client/client.js#L257

答案 1 :(得分:0)

我认为你所拥有的代码存在的问题是变量modalCallback是函数的本地变量(毕竟这是coffeescript)。

然而,正如您可能已经意识到的那样,这种方法实际上并不是正确的方法。问题是因为回调没有被保存在全局变量之外的任何地方,所以在热代码推送的情况下它将丢失。 (即在对话框打开时尝试点击保存在流星项目中的文件,看看随后关闭时会发生什么)。

这实际上是一个非常好的问题,我一直在考虑最好的方法。我现在最好的答案是使用全局响应回调。像这样:

Meteor.autorun(function() {
  if (Session.equals('lastDialog', 'alert-dialog') && 
      Session.equals('dialogOpen', false) && 
      Session.equals('lastDialogSuccess', true)) {
    alert("I'm alerting");

    // ensure it doesn't happen again, e.g. on another HCP
    Session.set('lastDialog', null);
  }
});

该代码需要处于顶层,因此它在HCP上重新运行。看看我设置的这个项目,试图找出一种更好的方法:https://github.com/tmeasday/dialog-experiment/tree/global-reactivity

或许更好的答案是“以更具声明性/反应性的方式做不同的事情”。我不确定。