2012-10-28 110 views
0

我創建了一個幫助器,用於在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或cancel按鈕時,它不會正確地反序列化它。

如何在用戶響應我的模態時執行回調?

回答

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

也許更好的答案是「以不同的方式做事,以更具說明性/更具反應性的方式」。我不確定。

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

+0

締約方搬到這裏:https://開頭github.com/meteor/meteor/tree/devel/examples/other/parties –