Wire Variables
Wire Variables
We can use @WireVariable
to wire variables from implicit objects or registered variable resolvers in a ViewModel as we do in a composer (please refer to ZK Developer's Reference/MVC/Controller/Wire Variables.
Because BindComposer wires those variables for us before calling initial method . But it will not
wire components and listeners automatically like a composer. To achieve it, please refer to Advance/Wire Components and Advance/Wire Event Listeners.
Wire from Implicit Objects
Wiring from implicit object is equivalent to calling Components.getImplicit(org.zkoss.zk.ui.Page, java.lang.String), by the name specified on @WireVariable
. If the name is absent and the field or method parameter is of type Execution, Page, Desktop, Session, or WebApp, it still will be wired to the correct implicit object. However, in other cases, an exception will be thrown.
public class FooViewModel {
@WireVariable
private Page _page;
@WireVariable
private Desktop _desktop;
@WireVariable
private Session _sess;
@WireVariable
private WebApp _wapp;
@WireVariable("desktopScope")
private Map<String, Object> _desktopScope;
}
Wire from Variable Resolver
First, you should register variable resolvers. There are two approaches to register a variable resolver: the VariableResolver annotation or the variable-resolver directive. Here is the example of registering variable resolvers with annotations.
@VariableResolver({foo1.MyResolver.class, foo2.AnotherResolver.class})
public class FooViewModel {
// class body
}
Then annotate fields or methods with the WireVariable annotation. For example,
@VariableResolver({foo1.MyResolver.class, foo2.AnotherResolver.class})
public class FooViewModel {
@WireVariable
Department department;
@WireVariable
public void setManagers(Collection<Manager> managers) {
// method body
}
}
Wire Spring-managed Beans
If you'd like to wire the Spring-managed beans, you usually register the Spring variable resolver, DelegatingVariableResolver. Then, you could annotate @WireVariable
for wiring a Spring managed bean. For example,
@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
public class PasswordViewModel {
@WireVariable
private User user;
}
DelegatingVariableResolver is a variable resolver used to retrieve the Spring-managed bean, so the variable will be retrieved and instantiated by Spring.
Notice that the variables are wired before instantiating the component and its children, so you can use them in EL expressions. For example, assume we have a ViewModel as follows.
@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
public class UserViewModel {
@WireVariable
private List<User> users;
public ListModel<User> getUsers() {
return new ListModelList<User>(users);
}
}
Then, you could bind it in the ZUL document. For example,
<grid model="@load(vm.users)">
You might make a ViewModel as a Spring bean then other beans used by the ViewModel can be injected by Spring, but it is not recommended. Please refer to ZK Developer's Reference/MVC/Controller/Wire Variables#Warning:_Not_a_good_idea_to_have_Spring_managing_the_composer for the reason.
Wire CDI-managed Beans
The approach to work with CDI is similar to the approach for Spring, except you should register another variable resolver for CDI: DelegatingVariableResolver.
Wiring Sequence
When wiring variables, the predefined sequence to look for variable resolvers is as follows:
- The variable resolver defined in the ZUML document.
- The variable resolver annotated registered in the class with the VariableResolver annotation.
- If none of above is found, it looks for the implicit objects, such as session and page.