-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hello everyone,
i hope someone can help me with the following problem:
I have an overview ZUL dialog with a ViewModel. Inside the ZUL, i want to include another ZUL dialog with its own ViewModel.
Now i want to pass some parameters from the first VIewModel to the second. I'm trying to achieve this via dynamic properties, i.e.
<include src="someFile.zul" folders="@load(overviewVM.folders)" />
But i cannot read the "folders"-param in the second ViewModel. I tried all the Param Annotations but they are all null. Using include in defer mode or using reference binding didn't help too. I assume this is a lifecycle problem, but how do i solve this?
Maybe a small diagram just to make things clear:
ViewModel1 ViewModel2 | | | | Overview.zul ------> <include src="someFile.zul"/> --------> someFile.zul
Thanks in advance.
It occurs to me that maybe you aren't aware that someFile.zul doesn't need it's own viewModel. As an included zul, it automatically has access to Overview.zul's viewmodel. So, in someFile.zul, you can just use overviewVM.folders in a component. You should look at any included zul as though it is in the same document as parent zul. No difference.
But, as a general principle of communicating between viewmodels, there are a few options. Personally, I would use one of these two techniques:
1) Push the folders object from viewmodel1 to viewmodel2 via an event queue. See here.
2) Make the folders object accessible via a session level attribute.
ViewModel1
Sessions.getCurrent().setAttribute("folders", folders);
Then, in ViewModel2, you can retrieve it via:
List<Folder> folders = Sessions.getCurrent().getAttribute("folders");
I don't know what type of object your folders is, so I just used List<Folder> for an example.
Ron
Hi Ron,
thanks for your help, however it seems i forgot to explain something. I want someFile.zul to be a single, universally usable Dialog which does not depend on others. So it has to have its own viewmodel. I want to call it directly, include it and create it via Executions.createComponents. Is this possible?
I think then, that this might help: http://books.zkoss.org/wiki/ZK%20Developer's%20Reference/MVVM/Advance/Access%20Arguments
That would address the include technique. For the .createComponents, you should be able to pass a Map as the third parameter. That Map contains the parameters you want the created component to have access to: http://books.zkoss.org/wiki/ZK_Developer's_Reference/UI_Composing/ZUML/Load_ZUML_in_Java
Unfortunately it did not solve the problem.
Maybe we should go for some example code:
package j17kiil$v2;
import org.zkoss.bind.annotation.ExecutionArgParam;
import org.zkoss.bind.annotation.Init;public class InnerVM {
private String passedText;
private String textFromZul;
@Init
public void init(@ExecutionArgParam("passedText") String passedText,
@ExecutionArgParam("textFromZul") String textFromZul) {
this.passedText = passedText;
this.setTextFromZul(textFromZul);
}public String getPassedText() {
return passedText;
}public void setPassedText(String passedText) {
this.passedText = passedText;
}public String getTextFromZul() {
return textFromZul;
}public void setTextFromZul(String textFromZul) {
this.textFromZul = textFromZul;
}
}
<zk>
<window border="none"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('innerVM') @init('j17kiil$v2.InnerVM')">
<label value="@bind(innerVM.passedText)" />
<label value="@bind(innerVM.textFromZul)" />
</window>
</zk>
package j17kiil$v2;
public class OuterVM {// could be loaded from database or whatever
private String textToPass = "textFromOuterViewModel";public String getTextToPass() {
return textToPass;
}public void setTextToPass(String textToPass) {
this.textToPass = textToPass;
}}
<zk>
<window border="none" id="outer"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('outerVM') @init('j17kiil$v2.OuterVM')">
<include src="inner.zul" passedText="@ref(outerVM.textToPass)" textFromZul="textDirectlyFromZUL" />
</window>
</zk>
If i specify the parameter directly in the zul code, i can access it in the inner view model. But if the parameter should be loaded from the outer view model, i have no chance to access it.
the lifecycle is not matched if you use include.src directly and want to access some args from execution (it is too late because the binder is working after creation, in afterCompose)
to achieve, there are some steps you have to follow.
1. change the src to binding too.
<include src="@init('inner.zul')" ..></include>
viewModel="@id('innerVM') @init('j17kiil$v2.InnerVM', theArg=passedText)"
I know it is not so straightforward.
Asked: 2012-11-16 21:16:53 +0800
Seen: 528 times
Last updated: Nov 19 '12