2015/3/16 updated:
Now the proxy object in form binding will auto-detect the changes of proxy object and form status. In this sample, the following code segment can be omitted : BindUtils.postNotifyChange(…);
Introduction
We are glad to disclose the firsthand information on one of the most to die for features in ZK 8 – New Form Binding Approach. It can deeply support these types – Collections, Map, and POJO in a form concept, as a proxy object for developers to manipulate them when users edit data in the form field. Once the form is submitted, all the edited data will be synchronized back to the original data object.
The following class diagram shows the difference of Form Binding implementation between ZK 7 series and ZK 8.0.
As shown in the diagram above, all user bean instances in the new Form Binding are proxy objects which can be used in the same way as the origin object without having to understand the underlying details of the Form Binding mechanism.
Books Management Demo
Here’s an example to demonstrate the form object (Book) with a collection property (Categories) in which users can edit the field data that belongs to Book or Categories in their own scope for caching.
In this demo, only the following 3 classes – BooksViewModel, Book, and Category are used:
With the new Form Binding, following the Java Proxy contract, the two classes – Book and Category needs to provide an empty constructor for the proxy mechanism to use. As shown in the diagram, in the Category class, we overwrite the hashcode and equals methods of the Category class to make sure only an unique category name exists.
Note: in the methods hashcode and equals, we cannot directly use the instance field to check, because the proxy object can be only handled by the method invocation, not the instance field. For example, use getName() instead of this.name.
In the BooksViewModel class, we provide 5 commands for the View to use.
- editable: used for detail grid to be editable.
@SmartNotifyChange("editable") @Command("editable") public void doEditable(@BindingParam("editable") boolean editable) { this.editable = editable; }
The @SmartNotifyChange is added since ZK 8.0, it means that notification is only triggered when the “editable” property has changed. Unlike @NotifyChange which triggers the notification every time.
- cancel: used to cancel all changes. In fact, when this method is being invoked, it will trigger a NotifyChange for the “currentBook” so that the form object (a proxy Book object and its descendant) will reload the data from the original object to itself.
@Command("cancel") @NotifyChange("currentBook") public void onCancel(@BindingParam("form") Form form) { //2015/3/16 updated, this line can be omitted //BindUtils.postNotifyChange(null, null, form.getFormStatus(), "."); }
As you can see here, we manually post a NotifyChange for the form status which is used in the zul page to switch the status of the cancel button. The parameter of “form” can be either a Form interface or a Book class, we use it as a Form interface in this case.
- save: used to save all changes from the form object to the original object and its descendants.
@Command("save") @NotifyChange({"currentBook", "editable"}) public void onSave() { this.editable = false; }
- addCategory: used to insert a new category to the form object.
@Command("addCategory") public void doAddCategory(@BindingParam("form") Book form, @BindingParam("cateName") String cateName) { Set
categories = (Set ) form.getCategories(); categories.add(new Category(cateName)); //2015/3/16 updated, the following two lines can be omitted //BindUtils.postNotifyChange(null, null, form, "categories"); //BindUtils.postNotifyChange(null, null, ((Form)form).getFormStatus(), "."); } The parameter of “form”, like we mentioned in the “cancel” command, is a proxy object of the “currentBook” instance of the BooksViewModel. The value returned from “form.getCategories()” is also a proxy object of the Set type for the “currentBook” instance.
As a result we add a new category object that only affects the proxy object (Set type), not the original set in the “currentBook” instance.
- removeCategory: used to remove a category from the form object.
@Command("removeCategory") public void doRemoveCategory(@BindingParam("form") Book form, @BindingParam("category") Category cate) { Set
categories = (Set ) form.getCategories(); categories.remove(cate); //2015/3/16 updated, the following two lines can be omitted //BindUtils.postNotifyChange(null, null, form, "categories"); //BindUtils.postNotifyChange(null, null, ((Form)form).getFormStatus(), "."); } Here the concept of the removing category is the same as the “addCategory” command.
In the zul file, there is nothing different from the past, the only new feature we add in ZK 8 is that we provide a cleanup concept for the form field within the form proxy object.
For example,
... // omitted ... // omitted ... // omitted |
Add Category
As shown above in line 11, the “fx.resetEmptyStringValue” expression is used to clean up the value of the textbox when user clicks the buttons “addCategory” or “cancel”.
If ZK doesn’t provide these built-in methods, developer needs to declare the “getResetEmptyStringValue()” method by themselves in their own POJO object or else they will be initiated as a form proxy object.
ZK 8 provides 9 built-in methods in the form proxy object transparently for developers to clean up the component value as follows.
- resetEmptyStringValue: returning an empty string value
- resetNullValue: returning a null value
- resetByteValue: returning a byte value (0)
- resetShortValue: returning a short value (0)
- resetIntValue: returning an int value (0)
- resetLongValue: returning a long value (0L)
- resetFloatValue: returning a float value (0.0f)
- resetDoubleValue: returning a double value (0.0d)
- resetBooleanValue: returning a boolean value (false)
- resetCharValue: returning a char value (‘\u0000′)
You may have noticed in line 3 of the example above, we used “@load(1)” to switch the template, this is a trick to make it work within the current ZK version. However, we will introduced another new concept called Shadow Element to do the same thing but in a more clever, powerful, and flexible way in ZK 8.0, we will talk this topic another time, please stay tuned.
Download
You can download the whole example from github.