2012-08-29 1 views
3

J'ai une exigence où je dois appeler une méthode Java GWT à partir d'un javascript, mais cela ne fonctionne pas. Aucune exception n'est levée mais l'application se bloque quelque part et le code ne s'exécute pas. L'application fonctionne bien lorsque je ne fais pas cet appel. Ma compilation GWT est réussie. Je suis en train de tester en mode dev dans Firefox.GWT appelant java méthode de javascript ne fonctionne pas

Mon code est quelque chose comme ça -

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); 
    } 

} 

Jusqu'à présent, je l'ai utilisé JSNI pour faire des appels simples comme wnd.close de $() ou wnd.alert $(), donc je pourrais manquer quelque chose. Est-ce que ma classe (où la méthode native et la méthode à appeler sont définies) doit étendre JavaScriptObject ou est-ce que cette méthode native doit être enregistrée en premier ou quelque chose?

Répondre

3

Je pense que vous avez un peu confus ici.

Votre code tel qu'il est ne fonctionnera que si vous avez déjà appelé jsCallViewDocument() à partir de votre code Java avant de cliquer sur le lien - sinon la fonction $wnd.jsCallViewDocument n'existera pas.

Cela n'aurait aucun sens dans ce cas de passer la chaîne dans la fonction.

Qu'est-ce que vous voulez sans doute est plutôt une fonction comme ceci:

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; 
}-*/; 

maintenant dans votre fonction 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

Je l'ai déjà invoqué. Votre raison n'est pas correcte mais votre code est correct. J'ai testé et découvert que l'utilisation de "ceci". directement était la cause du problème. L'assigner et l'utiliser a résolu le prob. var currentPage = ceci; mais le site de google utilise aussi ceci. @ quelque chose alors pourquoi cela n'a pas fonctionné est déroutant? Aussi l'entrée $ n'est pas nécessaire. Même l'enlever fonctionnait de la même manière.Mais de toute façon votre code le contient donc je l'ai marqué correctement. – abhihello123

+0

@weakstudent Vraiment? Je pense que ma raison est correcte; Vous semblez complètement confus sur le fonctionnement des méthodes JSNI et sur le fonctionnement des fonctions Javascript de première classe. Votre code initial était erroné car il assignait '$ wnd.jsCallViewDocument' au wrapper' $ entry() 'qui n'accepte pas de paramètre. Vous passiez également un paramètre inutilement dans la méthode native. Vous devez en apprendre davantage sur ces sujets avant d'écrire plus de code JSNI comme celui-ci - en particulier vous devez comprendre pourquoi votre code original était erroné. – funkybro

+0

'$ entry' est requis pour appeler Java depuis le code JSNI, voir ce commentaire pour plus d'informations: http://stackoverflow.com/questions/5234735/gwt-jsni-problem-passing-strings#comment5894088_5235580 Je vous suggère également google" Apprendre à connaître vraiment GWT "pour deux excellents blogs sur JSNI. Enfin, je vous suggère de lire Douglas Crockford pour l'ancrage en Javascript vous devez utiliser GWT et JSNI efficacement. – funkybro

0

Vous n'avez pas besoin javascript: dans onClick attribut (par opposition à href attribut)

passage à:

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

ou:

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

par la façon pourquoi ne pas assigner écouteur d'événement dans le code java gwt?

+0

Tomasz, javascript supprimé mais cela ne fait aucune différence. Dans mon cas, je dois faire un lien dans une colonne Listgrid (nom du document) qui devrait appeler une méthode personnalisée basée sur le nom du document cliqué. et il devrait apparaître comme lien hypertexte donc ne pense pas que l'écouteur d'événement peut fonctionner ici. Ici, si j'appelle jsCallViewDocument ("une chaîne de caractères") à partir de mon code, cela fonctionne. Mais quand je clique sur les liens qui apparaissent, aucune boîte d'alerte n'apparaît. – abhihello123

+0

@weakstudent: vous avez raison, si vous êtes obligé de retourner la chaîne plutôt que l'élément alors jsni semble être la seule solution. –

+0

lorsque je crée une méthode \t public natif vide myTest()/* - { \t \t $ wnd.jsCallViewDocument ('0911'); \t} - * /; et appelez myTest(). Il dit "Exception JavaScript non interceptée [window.jsCallViewDocument n'est pas une fonction]". Je pense que je dois d'abord enregistrer jsCallViewDocument() car il s'agit d'une méthode anonyme qui doit être analysée à l'exécution avant d'être appelée depuis Javascript. – abhihello123