While you're reading this, why not kick off a compile of your existing Errai project against the new release?
Do it now! It only takes a couple of minutes to switch the version number in your pom.xml to 2.2.0.CR1. If you're not using Maven, grab the release bits from our download page.
Seriously! We'll wait right here for you!
Client-side Bus Lifecycle
We've had questions over the years about how to find out exactly what the client-side message bus is up to: is it connected to the server? Is it attempting to reconnect? Has it given up and gone offline? Although there were ways to infer some of this information in the past, we decided it was time to make all of this information available in one place, and to make some guarantees about the order that these state transitions will happen in.
The best way to dive into the new bus lifecycle API would be to check out the BusStatusWidget that we added to the bus-stress-test demo, but here's a quick teaser:
class BusStatusLogger implements BusLifecycleListener {
@Override
public void busAssociating(BusLifecycleEvent e) {
GWT.log("Errai Bus trying to connect...");
}
@Override
public void busOnline(BusLifecycleEvent e) {
GWT.log("Errai Bus connected!");
}
@Override
public void busOffline(BusLifecycleEvent e) {
GWT.log("Errai Bus trying to connect...");
}
@Override
public void busDisassociating(BusLifecycleEvent e) {
GWT.log("Errai Bus going into local-only mode.");
}
}
To attach such a listener to the bus, just do the following in client-side code:
ClientMessageBus bus = (ClientMessageBus) ErraiBus.get();
bus.addLifecycleListener(new BusStatusLogger());
Nested Bindable Properties
We got good feedback about the data binding module that we added in Errai 2.1, which lets you bind properties from your model objects to GWT widgets (actually, to anything that implements HasValue). As a refresher, imagine you have an Item class with name and department properties, and a Department class with a name property of its own:
@Bindable
public class Item {
private String name;
private Department department;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Department getDepartment() { return department; }
public void setDepartment(Department department) { this.department = department; }
}
}
@Bindable
public class Department {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
}
Then you can link the value of item.name to a TextBox like this (this annotation-driven approach is provided by Errai UI):
@Templated("#main")
public class ItemWidget extends Composite {
@Inject private @AutoBound DataBinder<Item> itemBinder;
@Inject private @Bound @DataField TextBox name;
}
}
This is great, but what about the department name? We want a TextBox for that too! It became apparent pretty quickly that this feature would be way better if you could dig into the object graph and bind to nested properties, the data binding feature would cover a lot more use cases. Now you can:
@Templated
public class ItemWidget extends Composite {
@Inject private @AutoBound DataBinder<Item> itemBinder;
@Inject private @Bound @DataField TextBox name;
@Inject private @Bound(property="department.name") @DataField TextBox department;
}
That's it! The name of the Department object nested inside item will be kept in sync with the contents of the department textbox.
State Parameters in Page Navigation
The last big enhancement we want to call out is the addition of extra parameters to the page navigation framework. Following from the previous example, say your ItemWidget is also a @Page:
@Templated @Page("item")
public class ItemWidget extends Composite {
@Inject private @AutoBound DataBinder<Item> itemBinder;
@Inject private @Bound @DataField TextBox name;
@Inject private @Bound(property="department.name") @DataField TextBox department;
}
That's great: you can bookmark that you were at http://myapp.mycompany.com/#item. But which item were you looking at? That's important!
Now you can do this:
}
Now you can do this:
@Templated @Page("item")
public class ItemWidget extends Composite {
@Inject private @AutoBound DataBinder<Item> itemBinder;
@Inject private @Bound @DataField TextBox name;
@Inject private @Bound(property="department.name") @DataField TextBox department;
@PageState private int itemId;
@PageShowing
private void setupItem() {
itemBinder.setModel(findItem(itemId));
}
}
And presto! Your bookmarkable URL is now http://myapp.mycompany.com/#item;itemId=42.
We hope to enhance the navigation framework even more in Errai 3.0. Your input has been invaluable so far. Keep it coming!
Once again, I urge you to try your project against Errai 2.2.0.CR1 today! We truly believe this is the best and most stable release to date, so you have nothing to lose. And in the unlikely event that you do find a new issue, you'll be able to tell us before 2.2.0 goes final.
Happy coding,
The Errai Team