<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">What about aligning this more with the @EventHandler annotation we already have in the Errai UI module? I guess we can't reuse exactly that annotation since errai-data-binding doesn't depend on errai-ui, but maybe we can name it similarly, like @ModelChangeHandler or @PropertyChangeHandler?<div><br></div><div>-Jonathan</div><div><br><div><div>On 2013-03-12, at 9:59 AM, Christian Sadilek wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><meta http-equiv="Content-Type" content="text/html charset=us-ascii"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">I like the @OnModelChange proposal and agree it should also support specifying the property or a property list.<div><br></div><div>However, wouldn't @OldModel always equal @Source in the examples below? The source object is the object on which the event (change) occurred which should always be the old model object, or did I misunderstand? I mean if they are all optional it's fine but we can probably get away with one less annotation if we wanted to.</div><div><br></div><div>See:&nbsp;<a href="https://github.com/errai/errai/blob/master/errai-data-binding/src/main/java/org/jboss/errai/databinding/client/api/PropertyChangeEvent.java">https://github.com/errai/errai/blob/master/errai-data-binding/src/main/java/org/jboss/errai/databinding/client/api/PropertyChangeEvent.java</a></div><div><br></div><div>We could additionally support @OldValue and @NewValue for property specific change handlers:</div><div><div><br></div><div>@OnModelChange(propertyName="dob")</div><div>public void onMyModelChange(@OldValue Date oldDob,&nbsp;@NewValue&nbsp;Date&nbsp;newDob,&nbsp;@Source Object source)</div><div>{</div><div>&nbsp; &nbsp;// Perform date of birth change logic here</div><div>}</div></div><div><br></div><div>Cheers,</div><div>Christian</div><div><div><br><div><div>On 2013-03-12, at 7:36 AM, Eric Wittmann &lt;<a href="mailto:eric.wittmann@redhat.com">eric.wittmann@redhat.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">So two separate ideas here, right? &nbsp;First is hiding the DataBinder <br>(yes!) and the second is declarative change handlers for model updates.<br><br>Both are great ideas. &nbsp;So +1 to both.<br><br>The only thought I had on the declarative model change handler bit was <br>to have an *option* to be more specific with the declaration. &nbsp;In other <br>words, I might only care about one or two properties in my model. &nbsp;And I <br>might have very different logic that I want to perform for the different <br>properties. &nbsp;So it might be nice to target a single property name when <br>creating the change handler. &nbsp;Perhaps:<br><br><br>@OnModelChange(propertyName="firstName")<br>public void onMyModelChange(@OldModel MyModel model,<br> &nbsp;&nbsp;&nbsp;&nbsp;@NewModel MyModel newModel,<br> &nbsp;&nbsp;&nbsp;&nbsp;@Source &nbsp;&nbsp;&nbsp;&nbsp;Object source)<br>{<br> &nbsp;&nbsp;&nbsp;// Perform name-change logic here<br>}<br><br>@OnModelChange(propertyName="dob")<br>public void onMyModelChange(@OldModel MyModel model,<br> &nbsp;&nbsp;&nbsp;&nbsp;@NewModel MyModel newModel,<br> &nbsp;&nbsp;&nbsp;&nbsp;@Source &nbsp;&nbsp;&nbsp;&nbsp;Object source)<br>{<br> &nbsp;&nbsp;&nbsp;// Perform date of birth change logic here<br>}<br><br>Alternatively it could be:<br><br>@OnModelChange(properties={"firstName", "dob"})<br><br>And then method signature could remain the same.<br><br>-Eric<br><br>On 03/11/2013 08:42 PM, Mike Brock wrote:<br><blockquote type="cite">This gets us a little closer to something like this:<br><br>@Singleton<br>public class MyBean {<br><span class="Apple-tab-span" style="white-space:pre">        </span>@Inject @AutoBound MyModel model;<br><span class="Apple-tab-span" style="white-space:pre">        </span>@Inject @Bound Label name;<br><br><span class="Apple-tab-span" style="white-space:pre">        </span>public void onMyModelChange(@NewModel MyModel updatedModel) {<br> &nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>// do something with updatedModel<br><span class="Apple-tab-span" style="white-space:pre">        </span>}<br><br><span class="Apple-tab-span" style="white-space:pre">        </span>@ModelSetter<br><span class="Apple-tab-span" style="white-space:pre">        </span>public void setModel(MyModel model) {<br><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>this.model = model;<br><span class="Apple-tab-span" style="white-space:pre">        </span>}<br>}<br><br>Note that I didn't inject a DataBinder&lt;T&gt; but rather the MyModel directly. Also pay attention to the @ModelSetter annotation. The theory behind this is the DataBinder&lt;T&gt; would be created in the Bootstrapper but never actually injected. The @ModelSetter is a hint to create decorator code that proxies that method so the hidden DataBinder's setModel() method can be called, and then the proxied model object then passed on to the MyBean.setModel(). This requires AOP-style parodying of the MyBean in this case. But I think it's a powerful tradeoff.<br><br>Mike.<br><br>On 2013-03-11, at 8:33 PM, Mike Brock &lt;<a href="mailto:cbrock@redhat.com">cbrock@redhat.com</a>&gt; wrote:<br><br><blockquote type="cite">While I was playing tonight I had a few ideas I wanted to bounce off everyone. What about a higher level API for handling change events?<br><br>Consider the following:<br><br>====HelloWorld.java=========================================<br><br>@EntryPoint<br>@Templated("#root")<br>public class HelloWorld extends Composite {<br> &nbsp;@Inject @AutoBound private DataBinder&lt;MyModel&gt; model;<br><br> &nbsp;@Inject @NeedsData @Bound @DataField private TextBox name;<br> &nbsp;@Inject @DataField private Button button;<br><br> &nbsp;@EventHandler("button")<br> &nbsp;private void onClick(ClickEvent e) {<br> &nbsp;&nbsp;&nbsp;messageBox.setText("Hello there, " + model.getModel().getName());<br> &nbsp;}<br><br> &nbsp;&nbsp;@OnModelChange<br> &nbsp;&nbsp;public void onMyModelChange(@OldModel &nbsp;&nbsp;&nbsp;&nbsp;MyModel model,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@NewModel &nbsp;&nbsp;MyModel newModel,<br><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span> &nbsp;&nbsp;&nbsp;&nbsp;@Property &nbsp;&nbsp;String propertyName,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Source &nbsp;&nbsp;&nbsp;&nbsp;Object source) {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// react to change<br> &nbsp;&nbsp;}<br>}<br><br>----------------------------------------------------------------------------------------------------<br><br>====ChangeEvents.java======================================<br><br>@Singleton<br>public class ChangeEvents [<br> &nbsp;&nbsp;@OnGlobalModelChange<br> &nbsp;&nbsp;public void onMyModelChange(@OldModel &nbsp;&nbsp;&nbsp;&nbsp;MyModel model,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@NewModel &nbsp;&nbsp;MyModel newModel,<br><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span> &nbsp;&nbsp;&nbsp;&nbsp;@Property &nbsp;&nbsp;String propertyName,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Source &nbsp;&nbsp;&nbsp;&nbsp;Object source) {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// react to change<br> &nbsp;&nbsp;}<br>}<br><br>----------------------------------------------------------------------------------------------------<br><br>Note: the idea is that each of the specified attributes are optional with the exception you must specify *at least* @OldModel or @NewModel. So in practice you might just do something like this:<br><br>public void onMyModelChange(@NewModel MyModel updatedModel) {<br> &nbsp;&nbsp;// do something with updatedModel<br>}<br><br>The general idea is that the @ OnGlobalModelChange would match all *managed* (read: injected automatically by the container such as @AutoBound) DataBinders that match MyModel. Where-as the @OnModelChange in the HelloWorld class would be scoped just to that one ErraiUI bean.<br><br>----<br><br>This is just something I brainstormed in about 15 minutes. I am not fixed on this particular approach. But I found myself wanting a declarative way of listening for changes tonight that didn't involve me adding a @PostConstruct and manually adding a PropertyChangeHandler to the DataBinder.<br><br><br><br><br><br><br><br>_______________________________________________<br>errai-dev mailing list<br><a href="mailto:errai-dev@lists.jboss.org">errai-dev@lists.jboss.org</a><br><a href="https://lists.jboss.org/mailman/listinfo/errai-dev">https://lists.jboss.org/mailman/listinfo/errai-dev</a><br></blockquote><br><br>_______________________________________________<br>errai-dev mailing list<br><a href="mailto:errai-dev@lists.jboss.org">errai-dev@lists.jboss.org</a><br><a href="https://lists.jboss.org/mailman/listinfo/errai-dev">https://lists.jboss.org/mailman/listinfo/errai-dev</a><br><br></blockquote>_______________________________________________<br>errai-dev mailing list<br><a href="mailto:errai-dev@lists.jboss.org">errai-dev@lists.jboss.org</a><br><a href="https://lists.jboss.org/mailman/listinfo/errai-dev">https://lists.jboss.org/mailman/listinfo/errai-dev</a><br></blockquote></div><br></div></div></div>_______________________________________________<br>errai-dev mailing list<br><a href="mailto:errai-dev@lists.jboss.org">errai-dev@lists.jboss.org</a><br>https://lists.jboss.org/mailman/listinfo/errai-dev</blockquote></div><br></div></body></html>