0

我创建了一个助手,用于在我的 Meteor 应用程序(在咖啡脚本中)中显示通用模式。

这是 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,因此当用户单击确定或取消按钮时,它无法正确反序列化它。

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

4

2 回答 2

2

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

例如,请参阅此处的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

于 2013-02-03T16:09:53.247 回答
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

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

于 2012-11-12T06:46:59.973 回答