2012-08-29 40 views
3

我有一個要求,我必須從JavaScript調用一個Java GWT方法,但它不起作用。沒有發生異常,但應用程序在某處掛起而代碼無法運行。當我不打這個電話時,該應用程序工作正常。我的GWT編譯是成功的。我在Firefox中以開發模式進行測試。從JavaScript不工作的GWT調用java方法

我的代碼是這樣的 -

class CPClass { 

    public native void jsCallViewDocument(String objectId)/*-{ 
     $wnd.jsCallViewDocument = 
      $entry([email protected]::testJS(Ljava/lang/String;)(objectId)); 
    }-*/; 

    private void testJS(String objectId) { 
     SC.say("Call successfull" + objectId); 
    } 

    private void setDocName(ListGridRecord newRecord, someDTO currDocInfo) { 

     String anchorTag = "<a href ='#' onclick = \"javascript:jsCallViewDocument('" 
      + currDocInfo.getDocName() + "')\">" + currDocInfo.getDocName() + "</a>"; 

     newRecord.setAttribute(Display.GRID_FIELD_DOC_NAME, anchorTag); 
    } 

} 

到目前爲止我已經使用JSNI進行簡單的調用類似$ wnd.close()或$ wnd.alert(),所以我可能失去了一些東西。我的類(定義了Native方法和要調用的方法的地方)是否需要擴展JavaScriptObject,或者是首先要註冊的方法嗎?

回答

3

我想你在這裏有點困惑。

如果您已經在點擊鏈接之前從Java代碼中調用了jsCallViewDocument(),那麼您的代碼將保持原樣,否則$wnd.jsCallViewDocument函數將不存在。

在這種情況下將字符串傳遞給該函數是沒有意義的。

你可能就要什麼是這樣的功能:

public static native void setupJsCallViewDocument(CPClass p) /*-{ 
    var fn = function(objectId) { 
     // invoke our (Java) testJS function, passing objectId as a parameter 
     $entry(
      [email protected]::testJS(Ljava/lang/String;)(objectId) 
     ); 
    }; 

    // assign this function to the global jsCallViewDocument 
    $wnd.jsCallViewDocument = fn; 
}-*/; 

現在,在您setDocName功能:

private void setDocName(ListGridRecord newRecord, someDTO currDocInfo) { 
    // set up the native function call 
    setupJsCallViewDocument(this); 

    String anchorTag = "<a href ='#' onclick = \"javascript:jsCallViewDocument('" 
     + currDocInfo.getDocName() + "')\">" + currDocInfo.getDocName() + "</a>"; 

    newRecord.setAttribute(Display.GRID_FIELD_DOC_NAME, anchorTag); 
} 
+0

我已經調用了它。你的理由不正確,但你的代碼是正確的。我測試並發現使用「this」。直接是問題的原因。分配並使用它解決了問題。 var currentPage = this;但谷歌的網站也使用這個。@的東西,爲什麼它沒有工作是混亂? $條目也不需要。即使刪除它以同樣的方式工作。但反正烏爾代碼包含它,所以我標記它是正確的。 – abhihello123

+0

@weakstudent真的嗎?我認爲我的理由是正確的;您似乎對JSNI方法的工作方式以及Javascript一流功能的工作方式完全感到困惑。你最初的代碼是錯誤的,因爲它將'$ wnd.jsCallViewDocument'分配給不接受參數的'$ entry()'包裝器。您還將一個參數不必要地傳遞給本地方法。在編寫更多JSNI代碼之前,您需要了解更多關於這些主題的內容 - 尤其是您需要了解原始代碼錯誤的原因。 – funkybro

+0

從JSNI代碼調用Java需要'$ entry',請參閱此評論以獲取更多信息:http://stackoverflow.com/questions/5234735/gwt-jsni-problem-passing-strings#comment5894088_5235580我還建議您使用Google「開始真正瞭解GWT「,以獲得關於JSNI的兩個優秀博客。最後,我建議你閱讀道格拉斯克羅克福德爲JavaScript的基礎,你需要有效地使用GWT和JSNI。 – funkybro

0

你不需要javascript:onClick屬性(相對於href屬性)

開關:由爲何不分配事件偵聽器的方式

String anchorTag = "<a href = \"javascript:jsCallViewDocument('" 
     + currDocInfo.getDocName() + "')\">" + currDocInfo.getDocName() + "</a>"; 

String anchorTag = "<a href ='#' onclick = \"jsCallViewDocument('" 
     + currDocInfo.getDocName() + "')\">" + currDocInfo.getDocName() + "</a>"; 

或在java gwt代碼中?

+0

托馬斯,刪除的JavaScript:但是這並沒有什麼差別。在我的情況下,我必須在Listgrid列(文檔名稱)內創建一個鏈接,該鏈接應根據單擊的文檔名稱調用自定義方法。它應該顯示爲超鏈接,所以不要認爲事件監聽器可以在這裏工作。在這裏,如果我從我的代碼調用jsCallViewDocument(「一些字符串」)它的作品。但是當我點擊出現的鏈接時,不會出現警告框。 – abhihello123

+0

@weakstudent:你是對的,如果你被迫返回字符串而不是元素,那麼jsni似乎是唯一的解決方案。 –

+0

當我創建一個方法\t public native void myTest()/ * - { \t \t $ wnd.jsCallViewDocument('0911'); \t} - * /;並調用myTest()。它說「未捕獲的JavaScript異常[window.jsCallViewDocument不是函數]」。我認爲我必須首先註冊jsCallViewDocument(),因爲它是一個匿名方法,需要在運行前從Javascript調用它之前進行解析。 – abhihello123