New Features of ZK 8.0.0
Timothy Clare, Potix Corporation
May, 2015
ZK 8.0.0 RC
Introduction
The ZK team is proud to announce the release of ZK 8!
ZK 8's main focus was on improving
Download and Demo
Support Expression Language 3 (EL3)
introduce the new generation expression language of Java EE 7 – Expression Language 3 (EL 3) into ZK 8 so we can do more complicated and more powerful things with the newer expression language. There are many new features in EL 3 such as new operators, lambda expressions and collection operations. For more information on EL3 please take a look at the specification, JSR-341.
MENTION WORKS FOR JDK5
Lambda Expressions
Each converter is implemented with the capability to interpret lambda expressions defined in zul. The following shows an example of a textbox who's value and onOK command are both driven by lambdas.
<textbox value="@load((x -> (x * 100) / 2.54)(vm.value))"
onOK="@command('click', key=((x -> (x * 2.54) / 100)(self.value)))" />
The syntax used is same as ones in Java SE 8 and behaves like an anonymous function which is discarded after evaluated. We can name a lambda and evaluate indirectly.
Let us take the lambda expression (x -> (x * 100) / 2.54). In this case it will create an anonymous function which takes a value, multiplies it by 100 and divides the result by 2.54. This function is then applied to vm.value, where vm stands for our viewmodel.
To simplify this let us write some psuedo code for demonstration purposes.
myFunction = x -> (x * 100) / 2.54 //assign a lambda to myFunction temporarily
myFunction(vm.value) //execute myFunction passing vm.value as the parameter
While the above is just pseudo code to better help you understand the functionality it does demonstrate naming of lambdas, which is also possible. The following section outlines how to do this using two new operators.
New Operators
String Concatenation
String concatenation has been introduced to make it easy to construct strings within EL expressions. The following code snippet demonstrates how to do so.
<label value="@load(('Hi, ' += vm.firstname += ' ' += vm.lastname))" />
Assignment and Semicolons
Both assignment and semicolon operators are now implemented. Below shows an example of both being used.
<label value="@load((incr = x -> x + 1; incr(5)))" />
The assignment operator in this instance assigns a lambda function to incr which takes x, increments by 1 and then returns it.
incr = x -> x + 1
By using the ';' operator it evaluates the left hand side first, thus creating a lambda function incr, as previously discussed. Then evaluates and returns the right hand side. So in the following case:
<label value="@load((incr = x -> x + 1; incr(5)))" />
The value assigned to the label would be 6, as the lambda function is first evaluated and assigned to incr, then the incr(5) call is evaluated leading to a return value of 6.
Collection Operations
In ZK 8 it is now possible to use collection chain operations directly. In the example below we turn vm.names into stream() and then can create a pipeline of commands.
<listbox model="@load((vm.names.stream()
.filter(x -> x.contains(vm.filter))
.toList()))">
In addition to pipelines ZK 8's EL 3 supports easy collection construction using brackets ([ ]). The following example demonstrates this.
<label value="@load(([1, 2, 3, 4].stream().sum()))" />
Static Field and Method References
A static field or static method of a Java class can be referenced with the syntax Classname.Field, such as
<label value="@load((Math.sqrt(16)))" />
Please note that java.lang.* is imported by default.
Major MVVM Enhancements
Performance Increase
ZK 8 has brought about increases in MVVM binding performance, with both a memory consumption decrease and a response time increase. Below is the graph outlining these performance changes.
Memory improvements
ZK 8.0.0 RC requires much less memory than ZK 7.0.5 EE giving your application a boost just by upgrading. The graph plots the number of users against the memory used, where the lower the better.
Response Improvements
ZK 8.0.0 RC MVVM also responds quicker than ZK 7.0.5 EE. The graph below plots the number of users against the response time, where the lower the response time the better.
Recreating the tests
If you would like to recreate these tests above in your environment you can use the following code:
Java code
package org.zkoss.test;
import java.util.Collections;
import java.util.List;
public class ForEachVM {
private List<Integer> array = Collections.nCopies(30, 30);
public void setArray(List<Integer> array) {}
public List<Integer> getArray() {
return array;
}
}
ZUL
<zk xmlns:x="xhtml">
<div id="bind" apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('org.zkoss.test.ForEachVM')">
<div style="display:none" id="host">
<div children="@load(vm.array)">
<template name="children">
<div children="@load(vm.array)">
<template name="children">
Test Label
</template>
</div>
</template>
</div>
</div>
</div>
</zk>
SmartNotifyChange
ZK 8 brings about a change to the notify system. You are all used to @NotifyChange, however, ZK 8 has a better way, @SmartNotifyChange. Essentially the usage is exactly the same as @NotifyChange, except it will only notify the binder when a value has changed, unlike @NotifyChange. Thus it is more performant.
The following shows some example code:
public class OrderVM {
//other code...
//action command
@SmartNotifyChange({"selected","orders","messages"})
@Command
public void newOrder(){
Order order = new Order();
getOrders().add(order); //add new order to order list
selected = order;//select the new one
}
}
For more information please consult the ZK MVVM book and the new form binding blog.
MVVM support at the client
After listening to feedback the ZK team has introduced functionality in ZK 8 which allows developers to access ViewModel properties at the client. The following couple of code snippets demonstrates how to use this functionality.
Publishing a command using native component or direct invocation
<xhtml:button n:onClick="@command('doClick', {key:value, key1:valul1})"/>
wgt.$binder().command('doClick', args);
Subscribing to commands
wgt.$binder().after('commandName', callbackFuncation);
For more information please take a look at the ZK 8 Series Smalltalk.
BindingParam annotation supports converting from JSON to POJO automatically
ZK 8 now supports the ability to convert JSON sent to ZK into objects at the server automatically. Consider this example.
zkbind.$(someone).command('dataChange', {data:{title: "myData"}});
The above code will send JSON data to the command function "dataChange", this can be automatically converted into an appropriate object using the BindingParam.
public static class DataObject {
private String title;
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {return title;}
}
@Command
public void dataChange(@BindingParam("data") DataObject data) {
// do something here.
}
For more information please visit INSERT LINK HERE.
Children binding supports list model
In ZK 8, children binding supports a ListModel! This means you can separate the View and Model by implementing ListModel, which is used to provide data. Additionally, when you add/update/remove the data in the model, the corresponding components in children binding will be re-rendered at the same time.
When using List in children binding, to update data you have to use @NotifyChange to notify the binder any property changes, and the whole rendered components in children binding will be re-rendered at the same time.
The following example outlines the usage.
<vlayout children="@load(vm.model)">
<template name="children">
...
</template>
</vlayout>
private ListModelList model = new ListModelList();
...
@Command
public void add_model() {
Product newProduct = new Product(++count, "Microwave oven", 999);
model.add(newProduct);
}
For more information please take a look at our blog series on ZK 8 data binding.
FormattedTimeConverter introduced
ZK 8 has introduced a new converter named formattedTime. This makes it extremely easy to output a specific time using a specified format. The following shows an example of usage.
<label value="@load(item.time) @converter('formattedTime', format='hhmmss')"/>
For more information please refer to our ZK MVVM book.
New components & enhancements
Lightweight rich editor
Timepicker Component
Scrollview component
Shadow Elements
Page scope template
Parser supports disorder template tag
Support a shadow element concept for Databinding or EL expressions
Support client attribute data handler
Font Awesome upgrade
Introduced Danish language support
Comments
Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License. |