2010-01-25 10 views
4

En Javascript, je fais une forme SVG et l'ajout d'un gestionnaire de clic pour comme ceci:Utiliser ClickHandler avec un objet Javascript natif?

var rect = document.createElementNS('http://www.w3.org/2000/svg','rect'); 
    rect.addEventListener('click', myClickHandler, false); 

Cela fonctionne très bien. J'essaie de créer une classe Rect overlay dans GWT. Si possible, je voudrais simplement faire quelque chose comme ceci:

public class SVGRect extends JavaScriptObject { 

    public native void addClickHandler(ClickHandler handler) /*-{ 
     addEventListener('click', handler, false); 
    }-*/; 
} 

De cette façon, je peux passer un gestionnaire GWT « normal » à cette classe, et l'utiliser de l'extérieur comme tout autre élément UI GWT normal. Je ne sais pas comment connecter l'objet ClickHandler à l'implémentation javascript native de l'objet?

Merci

Répondre

3

Parce que vous avez besoin d'une ClickEvent pour passer à ClickHandler.onClick et l'obtenir à partir de JavaScript pose un problème (AFAICT) - Je vais avec un peu différent, approche plus « générique »:

Créer une simple interface de rappel:

public interface Callback { 
    void execute(); 
} 

Vous pouvez ensuite passer directement et l'appeler comme ceci:

public native void addClickHandler(Callback callback) /*-{ 
     addEventListener('click', function() { 
      [email protected]::execute()(); 
     }, false); 
}-*/; 

Ou créer une étape intermédiaire:

public void addClickHandler(Callback callback) { 
    _addClickHandler(getCallback(callback)); 
} 

private native void _addClickHandler(JavaScriptObject callback) /*-{ 
    addEventListener('click', callback, false); 
}-*/; 

// This can be moved to a better place 
private native static JavaScriptObject getCallback(Callback callback) /*-{ 
    return function() 
    { 
     [email protected]::execute()(); 
    }; 
}-*/; 

Et, bien sûr, vous voulez l'utiliser comme ceci:

SVGRect svg = getMeSVGRect(); 
svg.addClickHandler(new Callback() { 
    @Override 
    public void execute() { 
     // Do some stuff 
    } 
}); 

Personnellement, je préfère la deuxième solution - alors qu'il est plus de code, je j'aime garder mes méthodes natives/JSNI privées (sauf si c'est un objet superposé ou similaire) et le code est plus lisible et moins sujette aux erreurs (inutile d'utiliser la syntaxe funky pour appeler les fonctions Java depuis le code natif/JSNI).

+0

Génial, merci! – user246114

Questions connexes