我已经创建了一个帮助器,用于在我的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或取消按钮时,它不会正确反序列化。
当用户响应我的模态时,如何执行回调?
答案 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
或许更好的答案是“以更具声明性/反应性的方式做不同的事情”。我不确定。