-
1. Re: declarative data binding with GWT uIBinder injected widgets
csa Nov 7, 2013 8:42 PM (in response to anthony.f)1 of 1 people found this helpfulHi Anthony,
Yes, you can use declarative data binding without Errai UI. You have to make sure though that the bean that declares the @Bound fields is managed by Errai IOC. If you want to combine it with GWTs UiBinder you will need to inherit Errai's UiBinder module (and add the errai-uibinder jar to your classpath):
<inherits name="org.jboss.errai.uibinder.UIBinderForIOC" />
To make sure your bean is managed by Errai IOC, simply annotate it with a scope (e.g. @Dependent). You can then also simply inject UiBinder instances. That means you can replace code like this
public class EditContactView extends Composite { interface EditContactViewUiBinder extends UiBinder<Panel, EditContactView> {} private static EditContactViewUiBinder uiBinder = GWT.create(EditContactViewUiBinder.class); ... } }
with this
@Dependent public class EditContactView extends Composite { @Inject UiBinder<Panel, EditContactView> uiBinder; ... } ... }
EditContactView would contain all your @Bound @UiField. You can then @Inject this view anywhere you like (e.g. in your Presenter class if you use the MVP pattern).
Cheers,
Christian
-
2. Re: Re: declarative data binding with GWT uIBinder injected widgets
anthony.f Nov 8, 2013 5:32 AM (in response to csa)Hi Christian,
Thank you for your answer, I've added the module you specified, and now I'm having the following Errai modules :
<inherits name="org.jboss.errai.common.ErraiCommon" /> <inherits name="org.jboss.errai.ioc.Container" /> <inherits name="org.jboss.errai.databinding.DataBinding" /> <inherits name="org.jboss.errai.enterprise.CDI"/> <inherits name="org.jboss.errai.uibinder.UIBinderForIOC" />
But when I compile the app, I get the following error :
Computing all possible rebind results for 'org.jboss.errai.ioc.client.BootstrapperImpl.fr_carboatmedia_oasis_ui_client_professional_contact_clientEdi_composite_ProfessionalEdiAddContactPopup_UiBinder'
[INFO] Rebinding org.jboss.errai.ioc.client.BootstrapperImpl.fr_carboatmedia_oasis_ui_client_professional_contact_clientEdi_composite_ProfessionalEdiAddContactPopup_UiBinder [INFO] Invoking generator com.google.gwt.uibinder.rebind.UiBinderGenerator [INFO] [ERROR] Unable to find resource: org/jboss/errai/ioc/client/ProfessionalEdiAddContactPopupStyle.css [INFO] [ERROR] Can't interpret CSS [INFO] [ERROR] Could not find no-arg method named descriptionLabelCourt in type com.google.gwt.resources.client.CssResource [INFO] [ERROR] Errors in 'gen/org/jboss/errai/ioc/client/BootstrapperImpl.java' [INFO] [ERROR] Line 49: Failed to resolve 'org.jboss.errai.ioc.client.BootstrapperImpl.fr_carboatmedia_oasis_ui_client_professional_contact_clientEdi_composite_ProfessionalEdiAddContactPopup_UiBinder' via deferred binding [INFO] [WARN] For the following type(s), generated source was never committed (did you forget to call commit()?) [INFO] [WARN] org.jboss.errai.ioc.client.BootstrapperImpl_fr_carboatmedia_oasis_ui_client_professional_contact_clientEdi_composite_ProfessionalEdiAddContactPopup_UiBinderImpl [INFO] Computing all possible rebind results for 'org.jboss.errai.ioc.client.QualifierEqualityFactory' [INFO] Rebinding org.jboss.errai.ioc.client.QualifierEqualityFactory [INFO] Invoking generator org.jboss.errai.ioc.rebind.ioc.bootstrapper.QualifierEqualityFactoryGenerator [INFO] Generating Extensions Bootstrapper... [INFO] Rebinding org.jboss.errai.ioc.client.QualifierEqualityFactory [INFO] Invoking generator org.jboss.errai.ioc.rebind.ioc.bootstrapper.QualifierEqualityFactoryGenerator
So I tried to replace all the modules by only this one :
<inherits name="org.jboss.errai.enterprise.All" />
But I'm also getting an error :
[INFO] generating ioc bootstrapping code... [ERROR] java.util.concurrent.ExecutionException: org.jboss.errai.ioc.rebind.ioc.exception.UnsatisfiedDependenciesException: @> fr.carboatmedia.oasis.ui.client.professional.contact.clientEdi.composite.ProfessionalEdiAddContactPopup [ERROR] - field org.jboss.errai.codegen.meta.MetaField:fr.carboatmedia.oasis.ui.client.professional.contact.clientEdi.composite.ProfessionalEdiAddContactPopup.uiBinder could not be satisfied for type: com.google.gwt.uibinder.client.UiBinder [ERROR] Message: can't resolve bean: com.google.gwt.uibinder.client.UiBinder<com.google.gwt.user.client.ui.Widget, fr.carboatmedia.oasis.ui.client.professional.contact.clientEdi.composite.ProfessionalEdiAddContactPopup> ( @Default @Any )
I'm injecting the uibinder in my view, and view is created throw IOC :
@Dependent public class ProfessionalEdiAddContactPopup extends Composite { @Inject private UiBinder<Panel, ProfessionalEdiAddContactPopup> uiBinder;
Thanks for your help !
-
3. Re: declarative data binding with GWT uIBinder injected widgets
anthony.f Nov 8, 2013 6:15 AM (in response to anthony.f)One more thing,
If i create the UiBinder with the GWT way :
interface ProfessionalEdiAddContactPopupUiBinder extends UiBinder<Widget, ProfessionalEdiAddContactPopup> {} private ProfessionalEdiAddContactPopupUiBinder uiBinder = GWT.create(ProfessionalEdiAddContactPopupUiBinder.class); The app compiles and the binding works like a charm
So the only remaining problem is that I'm not able to directly @Inject the UiBinder
-
4. Re: declarative data binding with GWT uIBinder injected widgets
csa Nov 8, 2013 11:30 AM (in response to anthony.f)Hi Anthony,
That's good news! For the UiBinder to be injectable you will still need to inherit the errai-uibinder module. It is not included in errai-javaee-all.
Cheers,
Christian
-
5. Re: Re: declarative data binding with GWT uIBinder injected widgets
anthony.f Nov 13, 2013 10:34 AM (in response to csa)Hi,
The problem is still here bu I have some fresh news.
In my uiBinder xml file, I define the css resource like that :
<ui:style src="ProfessionalEdiAddContactPopupStyle.css" />
Injecting the UiBinder with errai produces the following error at compile time :
Computing all possible rebind results for 'org.jboss.errai.ioc.client.BootstrapperImpl.fr_carboatmedia_oasis_ui_client_professional_contact_clientEdi_composite_ProfessionalEdiAddContactPopup_UiBinder' [INFO] Rebinding org.jboss.errai.ioc.client.BootstrapperImpl.fr_carboatmedia_oasis_ui_client_professional_contact_clientEdi_composite_ProfessionalEdiAddContactPopup_UiBinder [INFO] Invoking generator com.google.gwt.uibinder.rebind.UiBinderGenerator [INFO] [ERROR] Unable to find resource: org/jboss/errai/ioc/client/ProfessionalEdiAddContactPopupStyle.css [INFO] [ERROR] Errors in 'gen/org/jboss/errai/ioc/client/BootstrapperImpl.java' [INFO] [ERROR] Line 52: Failed to resolve 'org.jboss.errai.ioc.client.BootstrapperImpl.fr_carboatmedia_oasis_ui_client_professional_contact_clientEdi_composite_ProfessionalEdiAddContactPopup_UiBinder' via deferred binding [INFO] [WARN] For the following type(s), generated source was never committed (did you forget to call commit()?) [INFO] [WARN] org.jboss.errai.ioc.client.BootstrapperImpl_fr_carboatmedia_oasis_ui_client_professional_contact_clientEdi_composite_ProfessionalEdiAddContactPopup_UiBinderImpl_GenCss_style [INFO] [WARN] org.jboss.errai.ioc.client.BootstrapperImpl_fr_carboatmedia_oasis_ui_client_professional_contact_clientEdi_composite_ProfessionalEdiAddContactPopup_UiBinderImpl_GenBundle [INFO] [WARN] org.jboss.errai.ioc.client.BootstrapperImpl_fr_carboatmedia_oasis_ui_client_professional_contact_clientEdi_composite_ProfessionalEdiAddContactPopup_UiBinderImpl
The interesting line is this one :
[ERROR] Unable to find resource: org/jboss/errai/ioc/client/ProfessionalEdiAddContactPopupStyle.css
Errai is looking for my CSS file in the wrong folder.
BUT, if if define my CSS file with an absolute path (e.g. com/mycompany/ProfessionalEdiAddContactPopupStyle.css) rather than a relative one, it works. This bug does not occures when the UiBinder is created with the GWT.create(), so it could be a bug coming from errai.
Once this problem is solved, another one appears. Here is one attribute of my view :
@UiField @Bound(property = "email") TextBox mailTextBox;
Errai produces the following errors at compile time :
[INFO] [ERROR] Errors in 'C:\dev\workspaces\oasis\oasis_trunk\oasis-ui\target\.generated\org\jboss\errai\ioc\client\BootstrapperImpl_fr_carboatmedia_oasis_ui_client_professional_contact_clientEdi_composite_ProfessionalEdiAddContactPopup_UiBinderImpl.java' [INFO] [ERROR] Line 171: The field ProfessionalEdiAddContactPopup.mailTextBox is not visible
I had to declare my attribute as 'public' in order to make this error disappeared, but using @UiField on attributes with a visibility different than 'public' works well with the classic GWT UiBinder.
Once I declared all my injected widget as public, I encountered a new Error message ;
[INFO] 16:28:57.104 [pool-4-thread-5] WARN o.jboss.errai.config.rebind.EnvUtil - reachability analysis disabled. errai may generate unnecessary code. [INFO] 16:28:57.104 [pool-4-thread-5] WARN o.jboss.errai.config.rebind.EnvUtil - enable reachability analysis with -Derrai.compile.perf.perform_reachability_analysis=true [INFO] 16:28:57.104 [pool-4-thread-5] INFO o.j.e.m.r.MarshallerGeneratorFactory - generating marshalling class... [INFO] 16:28:57.174 [pool-4-thread-5] INFO o.j.e.m.r.MarshallerGeneratorFactory - generated marshalling class in 70ms. [ERROR] org.jboss.errai.codegen.exception.UndefinedMethodException: undefined method: _$807284019__$1937953969_partnerListBox(fr.carboatmedia.oasis.ui.client.professional.contact.clientEdi.composite.ProfessionalEdiAddContactPopup, fr.carboatmedia.oasis.ui.client.common.custom.SelectListBox); in class: org.jboss.errai.ioc.client.BootstrapperImpl [ERROR] at org.jboss.errai.codegen.builder.callstack.MethodCall.handleCall(MethodCall.java:73) [ERROR] at org.jboss.errai.codegen.builder.callstack.AbstractCallElement.nextOrReturn(AbstractCallElement.java:46) [ERROR] at org.jboss.errai.codegen.builder.callstack.LoadClassReference.handleCall(LoadClassReference.java:48) [ERROR] at org.jboss.errai.codegen.builder.impl.AbstractStatementBuilder.generate(AbstractStatementBuilder.java:61) [ERROR] at org.jboss.errai.codegen.BlockStatement.generate(BlockStatement.java:90) [ERROR] at org.jboss.errai.codegen.control.IfBlock.generate(IfBlock.java:65) [ERROR] at org.jboss.errai.codegen.builder.callstack.ConditionalBlockCallElement.handleCall(ConditionalBlockCallElement.java:46) [ERROR] at org.jboss.errai.codegen.builder.impl.AbstractStatementBuilder.generate(AbstractStatementBuilder.java:61)
For this error, I didn't find any dirty solution yet :s
I hope all this details will help you to fix or improve this great api .
Cheers,
Anthony.
-
6. Re: declarative data binding with GWT uIBinder injected widgets
csa Nov 13, 2013 12:32 PM (in response to anthony.f)Hi Anthony,
Thanks for digging into this. We haven't really continued development on Errai's UiBinder module ever since we added Errai UI. Since you already have Errai's declarative data binding working with GWTs native UiBinder I'd recommend leaving out Errai's UiBinder module for now. Of course you're welcome to send a pull request with a fix to this module if you're interested and/or create a JIRA for us!
Cheers,
Christian
-
7. Re: declarative data binding with GWT uIBinder injected widgets
anthony.f Nov 13, 2013 12:40 PM (in response to csa)Thanks for your answer.
I will continue to use GWT native UiBinder for now, And I'll make a pull request or a jira if I don't have enough time for the pull .
Cheers,
Anthony
-
8. Re: Re: declarative data binding with GWT uIBinder injected widgets
nickalexander Dec 9, 2013 7:51 AM (in response to csa)Hi, Just some more on this,
I have been having a similar issue.
Regardless if I use the Injected uiBinder or the GWT.create one I cannot get declarative binding to work.
I have managed to get binding to to work using the @PostConstruct annotated method with something like this
@PostConstruct
public void init() {
initWidget(uiBinder.createAndBindUi(this));
ContactImpl contact = contactBinder
.bind(firstName, "firstName")
.bind(lastName, "lastName")
.getModel();
contact.setFirstName("Mad");
contact.setLastName("Max");
}
but allow get a org.jboss.errai.codegen.exception.UndefinedMethodException
when using the declarative binding. This is really pain.
Will have a look at the code to see whats there. Another issue is that Binding requires HasValue or HasText interface on the widget according to the BindableProxyAgent javadoc although this is not mentioned anywhere in the Wiki. Would it not make sense to support standard GWT Editors and Adaptors for Data-binding?
Nick
-
9. Re: declarative data binding with GWT uIBinder injected widgets
csa Dec 9, 2013 11:05 AM (in response to nickalexander)Hi Nick,
Although we've been focusing on Errai UI because we think it's a better alternative to UiBinder you should still be able to at least make declarative binding work with GWT's UiBinder (as Anthony and others did).
Can you provide all exception details of the UndefinedMethodException you're getting (error message and stacktrace)? Using GWT.create instead of the injected UiBinder and removing Errai's UiBinder module from your gwt.xml and classpath should make the problem go away.
Regarding GWT Editors, I am not sure that would make sense, to be honest. The GWT Editor framework is really an alternative approach to data binding. I am not sure about the benefits of mixing these two other than migrating existing code.
Cheers,
Christian
-
10. Re: Re: declarative data binding with GWT uIBinder injected widgets
nickalexander Dec 13, 2013 3:49 AM (in response to csa)Hi Christian, did a GIT Pull and have isolated the bug.
org.jboss.errai.databinding.rebind.BoundDecorator in the generateDecorator method
if (widgetType.isAssignableTo(Widget.class)) {
// Ensure @Bound widget field is initialized
if (!ctx.isAnnotationPresent(UiField.class) && !ctx.isAnnotationPresent(Inject.class) && ctx.getField() != null && widgetType.isDefaultInstantiable()) {
Statement widgetInit = Stmt.invokeStatic(
ctx.getInjectionContext().getProcessingContext().getBootstrapClass(),
PrivateAccessUtil.getPrivateFieldInjectorName(ctx.getField()),
Refs.get(ctx.getInjector().getInstanceVarName()),
ObjectBuilder.newInstanceOf(widgetType));
statements.add(If.isNull(widget).append(widgetInit).finish());
}
}
I added the condition check for the UIField as the ctx.getInjectionContext().getProcessingContext().getBootstrapClass() call references a non existing field in the BootStrapper class.
This is obviously not a complete solution to the problem as it does not address UIFactory methods or UIField(provided=true), I will look at addressing this issues if i have time and write some tests around this.
Nick Alexander
-
11. Re: declarative data binding with GWT uIBinder injected widgets
csa Dec 16, 2013 4:23 PM (in response to nickalexander)Hi Nick,
Great! Can you send us a pull request if this fixes your issue? Writing a unit test for it should also be straight forward and similar to:
Cheers,
Christian