2011-01-09 3 views
1

J'essaie d'accéder à certains objets à l'intérieur d'un composant ui: classeur, mais je ne suis pas sûr de la façon d'accéder à eventBus, requestFactory, etc sans écrire de code méchant Tenez-moi réveillé la nuit (prenez également note que je suis complètement nouveau à JAVA, l'arrière-plan est en Perl/Python/PHP).Spring ROO GWT avec injection GIN sur les widgets créés par ui: classeur

Mon fichier ui.xml:

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' 
    xmlns:g='urn:import:com.google.gwt.user.client.ui' 
    xmlns:ig='urn:import:com.ig.client.scaffold.ui.widget'> 
    <ui:style> 
     ... 
    </ui:style> 
    <g:HorizontalPanel> 
     ... 
    </g:HorizontalPanel> 
</ui:UiBinder> 

Injecter la EventBus cette façon échoue avec com.ig.client.scaffold.ui.widget.R n'a pas de constructeur par défaut (zéro args).

public class R extends Composite { 

    interface MyUiBinder extends UiBinder<Widget, R> {} 
    private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class); 

    private final EventBus eventBus; 

    @UiField SimplePanel fieldA, ...; 

    @Inject 
    public R(EventBus eventBus){ 
     this.eventBus = eventBus; 
     initWidget(uiBinder.createAndBindUi(this)); 
    } 
} 

Ainsi, selon le message d'erreur, je crée un UIFactory puis je reçois une erreur ... '{style.entityComponent}> manquant attribut requis (s): EventBus Element ... (semble qu'il essaie de trouver le EventBus dans l'interface. liant stylesheet

public class R extends Composite { 

    interface MyUiBinder extends UiBinder<Widget, R> {} 
    private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class); 

    private final EventBus eventBus; 

    @UiField SimplePanel fieldA, ...; 

    public @UiConstructor R(EventBus eventBus){ 
     this.eventBus = eventBus; 
     initWidget(uiBinder.createAndBindUi(this)); 
    } 

    @Inject 
    @UiFactory R makeR(){ 
     return new R(eventBus); 
    } 
} 

à la lecture et à la lecture et plus de lecture pour les deux derniers jours, je n'ai pas vu quelqu'un d'accéder au EventBus, requestFactory et historyController directement dans la vue liée à l'ui: widget liant qui a conduit à la conclusion que ce n'est probablement pas une bonne pratique a nyway.

Disons que j'ai un objet, appelons-le Proxy, le proxy contient handleButtonClick qui appelle eventBus.doSomething(). Comment lier cet objet Proxy au widget ui: liinder sans avoir à l'instancier ou sans le passer à chaque widget?

Est-il possible de faire une injection GIN sur une interface, puis d'implémenter cette interface via la classe R qui contiendra alors en quelque sorte les objets que je cherche?

Toute solution qui fonctionne est la bienvenue, juste à la recherche d'un échantillon (qu'un Java n00b peut comprendre) qui me permettra fondamentalement de connecter mon front-end avec le reste des services créés par ROO.

Merci J

Répondre

2

Vérifiez la Model, View, Presenter pattern - il résout ce problème. En général, toute logique non affichée doit être conservée pour que 1) la logique non affichée puisse être testée sans unité fonctionnant dans un navigateur (lent à instancier) et 2) différents affichages peuvent être branchés dans le même application sans dupliquer la logique de non-affichage.

Voici un exemple montrant le comportement MVP que vous recherchez (notez que le style est légèrement différent que les activités & Places de mise en œuvre).

MyPresenter.java:

public class MyPresenter { 
    public interface Display extends IsWidget { 
    void setButtonClickHandler(ClickHandler buttonClickHandler); 
    } 

    private final Display display; 
    private final EventBus eventBus; 

    @Inject 
    public MyPresenter(EventBus eventBus, 
        Display display) 
    { 
    this.display = display; 
    this.eventBus = eventBus; 

    bind(); 
    } 

    private void bind() { 
    display.setButtonClickHandler(new ClickHandler() { 
     @Override 
     public void onClick(ClickEvent event) { 
     eventBus.fireEvent(new MyButtonClickedEvent()); 
     } 
    }); 
    } 

    public void go(HasWidgets container) { 
    container.add(display.asWidget()); 
    } 
} 

MyView.ui.xml:

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' 
    xmlns:g='urn:import:com.google.gwt.user.client.ui' 
    xmlns:ig='urn:import:com.ig.client.scaffold.ui.widget'> 

    <g:Button ui:field="myButton"/> 
</ui:UiBinder> 

MyView.java

public class MyView extends Composite implements MyPresenter.Display { 
    interface MyViewUiBinder extends UiBinder<Widget, MyView> {} 
    private static MyViewUiBinder uiBinder = GWT.Create(MyViewUiBinder.class); 

    private ClickHandler buttonClickHandler = null; 

    public MyView() { 
    initWidget(uiBinder.createAndBindUi(this)); 
    } 

    @UiHandler("myButton") 
    void onButtonClick(ClickEvent event) { 
    if (buttonClickHandler != null) { 
     buttonClickHandler.onClick(event); 
    } 
    } 

    @Override 
    public void setButtonClickHandler(ClickHandler buttonClickHandler) { 
    this.buttonClickHandler = buttonClickHandler; 
    } 
} 

Et dans votre module GIN: bind(MyPresenter.Display.class).to(MyView.class);

+0

Merci Jason, je lisais MVP docs de Google Code, ce matin, et il semblait être exactement ce que je cherchais, mettra en œuvre ce soir. Merci un million :-) –

+0

Salut Jason, je ne vais pas obtenir votre exemple de travail, avez-vous la source disponible pour moi ou cela vous dérangerait de regarder mon code et de signaler le problème - je ne reçois pas la liaison à travailler et ont lutté pendant des semaines maintenant. –

+0

Pourquoi ne posez-vous pas une nouvelle question spécifique au problème que vous rencontrez et créez un lien à partir d'un commentaire ici pour que je puisse le voir? –