2013-12-10 37 views
0

爲了避免用戶重複點擊相同的按鈕和同理髮送多個請求到服務器,我已經使用了以下模式:GWT按鈕單擊啓用/禁用模式 - 在開發模式GwtEvent assertLive()

  1. 在按鈕ClickHandler.onClick中,禁用該按鈕。
  2. 回撥時,重新啓用按鈕。

請參閱下面的代碼模式。下面的「rpcCall」函數基本上是Button onClick(最終ClickEvent事件)的核心實現。

private void rpcCall(final ClickEvent event) 
{ 
    final AsyncCallback<Void> callback = new AsyncCallback<Void>() 
    { 
    @Override 
    public void onSuccess(Void result) 
    { 
     final Button source = (Button) event.getSource(); // Dev mode isLive assertion failure. 
     source.setEnabled(true); 
     // Process success... 
    } 
    @Override 
    public void onFailure(Throwable caught) 
    { 
     final Button source = (Button) event.getSource(); 
     source.setEnabled(true); 
     // Process error... 
    } 
    }; 
    // Disable sender. 
    final Button source = (Button) event.getSource(); 
    source.setEnabled(false); 
    // RPC call. 
    final RpcAsync rpcAsync = getRpcAsync(); 
    RpcAsync.rpcCall(..., callback); 
} 

我只注意到「此事件已完成被其原始處理程序經理處理,這樣你就可以不再訪問」造成的開發模式下將isLive斷言失敗異常時的onSuccess異步函數調用事件.getSource()。

雖然它似乎在生產/ JavaScript模式下工作。

此dev模式斷言失敗讓我質疑這種模式。

這是一個很好的模式嗎?爲什麼我只能在開發模式下獲得異常?什麼會是更好的模式?

顯然,我可以通過傳遞source Button作爲rpc wrapper調用函數的參數來繞過對event.getSource()的調用,但對於已經攜帶此類引用的事件對象來說似乎是多餘的。

回答

2

從歷史上看,您在IE中獲得事件對象的方式是使用window.event,這隻持續了處理事件的時間。 GWT的Event因此不得不放棄看守,所以你不願意保留一個事件實例,因爲它可能突然反映正在處理的另一個事件,或根本沒有事件(奇怪!)
幸運的是,微軟已經修復了它們瀏覽器,這就是爲什麼當你測試它時它工作(我敢打賭你沒有在IE6中測試;-))。

來處理這種情況的正確方式是提取所有您從事件所需要的數據,並讓他們在final變量:

private void rpcCall(final ClickEvent event) 
{ 
    final Button source = (Button) event.getSource(); 

    final AsyncCallback<Void> callback = new AsyncCallback<Void>() 
    { 
    @Override 
    public void onSuccess(Void result) 
    { 
     source.setEnabled(true); 
     // Process success... 
    } 
    @Override 
    public void onFailure(Throwable caught) 
    { 
     source.setEnabled(true); 
     // Process error... 
    } 
    }; 
    // Disable sender. 
    source.setEnabled(false); 
    // RPC call. 
    final RpcAsync rpcAsync = getRpcAsync(); 
    RpcAsync.rpcCall(..., callback); 
}