2014-02-12 95 views
2

我有一個jq替換標準確認對話框。jQuery包裝推遲和承諾

我允許用戶傳入一個函數,如果用戶點擊確定就會被調用。

傳入的函數可能會調用像ajax調用一樣的長時間運行異步任務,有時候不會,我想迎合這兩者。

我用這個解決方案爲基礎(https://stackoverflow.com/a/19374933

我想實現的是這樣的:

MyConfirmation('A Title', 'A message to the user', function() { 
    $.get('/some/bigdata/longrunning'); 
} 
).then(function() { 
    // add to dom here 
}); 

這是MyConfirmation:

MyConfirmation = function (title, message, ok) { 
    var d = $.Deferred(); 
    $('<div/>') 
     .text(message) 
     .dialog({ 
        buttons: { 
       "Ok": function() { 
        if($.isFunction(ok)) { 
         ok.apply(); 
        } 
        $(this).dialog("close"); 
        d.resolve(true); 
        return true; 
       }, 
       "Cancel": function() { 
        $(this).dialog("close"); 
        d.resolve(false); 
        return false; 
       } 
      }, 
      close: function(event, ui) { 
       $(this).remove(); 
      }, 
      resizable: false, 
      draggable: false, 
      width: 'auto', 
      title: title, 
      modal: true 
     }); 

    return d.promise(); 
}; 

我想最好結合我的延期返回真或假,以指示用戶點擊確定或取消。

我知道我可以使用的承諾中,.done方法從$不用彷徨返回,但我會怎麼做我的解決方案的工作

回答

1

我我允許用戶傳入一個函數,如果用戶點擊ok,它將被調用。

不要。從MyConfirmation函數中刪除ok參數,只返回按鈕點擊的承諾。然後,用戶可以根據需要鏈接他的功能 - 或者做更多。

您的電話,而應該是這樣的:

MyConfirmation('A Title', 'A message to the user').then(function(okPressed) { 
    if (okPressed) 
     return $.get('/some/bigdata/longrunning'); 
}).then(function(longruningResult) { 
    // add to dom here 
}); 

您可能還reject()按下承諾當取消按鈕,那麼你就需要一個布爾okPressed檢查,並可以使用一個單獨的錯誤代替。

+1

我是**只是**將我自己的答案標記爲接受,然後閱讀這個更優雅的解決方案。另外我也從中學到了一些東西。謝謝。 –

0

我認爲你應該使用Ajax調用的返回承諾:

MyConfirmation('A Title', 'A message to the user', function() { 
    return $.get('/some/bigdata/longrunning'); 
} 
).then(function() { 
    // add to dom here 
}); 

MyConfirmation功能:

MyConfirmation = function (title, message, ok) { 
    var d = $.Deferred(); 
    $('<div/>') 
     .text(message) 
     .dialog({ 
        buttons: { 
       "Ok": function() { 
        if($.isFunction(ok)) { 
         ok().then(function() { 
          d.resolve(true); 
         }); 
        } 
        $(this).dialog("close"); 
        return true; 
       }, 
       "Cancel": function() { 
        $(this).dialog("close"); 
        d.resolve(false); 
        return false; 
       } 
      }, 
      close: function(event, ui) { 
       $(this).remove(); 
      }, 
      resizable: false, 
      draggable: false, 
      width: 'auto', 
      title: title, 
      modal: true 
     }); 

    return d.promise(); 
}; 

這增加了一個條件,以解決該對話框遞延,從阿賈克斯承諾本身

聲明:未經測試:)

0

繼續從Pandaiolo的迴應,我意識到我應該在我的調用函數中返回ajax調用。當傳入的函數完成時,這和我自己的鏈接延遲。

一個小的調整,以便對付那些情況下,當傳遞函數不返回(通過使用$.when)遞延和它的作品(見How can I determine if a jQuery object is deferred?

MyConfirmation變爲:

MyConfirmation = function (title, message, ok) { 
    var d = $.Deferred(); 
    $('<div/>') 
     .text(message) 
     .dialog({ 
        buttons: { 
       "Ok": function() { 
        if($.isFunction(ok)) { 
         $.when(ok.apply()).then(function() { 
          d.resolve(true); 
         }); 
        } else { 
         d.resolve(true); 
        } 
        $(this).dialog("close"); 
        return true; 
       }, 
       "Cancel": function() { 
        $(this).dialog("close"); 
        d.resolve(false); 
        return false; 
       } 
      }, 
      close: function(event, ui) { 
       $(this).remove(); 
      }, 
      resizable: false, 
      draggable: false, 
      width: 'auto', 
      title: title, 
      modal: true 
     }); 

    return d.promise(); 
};