0

How to pass parameters from ViewModel to ViewModel via <include>?

asked 2012-11-16 21:16:53 +0800

cypha gravatar image cypha
27 1

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.

delete flag offensive retag edit

6 Replies

Sort by ยป oldest newest

answered 2012-11-17 02:37:09 +0800

rdgrimes gravatar image rdgrimes
735 7

updated 2012-11-17 02:50:54 +0800

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

link publish delete flag offensive edit

answered 2012-11-17 08:11:30 +0800

cypha gravatar image cypha
27 1

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?

link publish delete flag offensive edit

answered 2012-11-17 17:39:21 +0800

rdgrimes gravatar image rdgrimes
735 7

updated 2012-11-17 17:48:38 +0800

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

link publish delete flag offensive edit

answered 2012-11-18 12:17:35 +0800

cypha gravatar image cypha
27 1

Unfortunately it did not solve the problem.
Maybe we should go for some example code:

ZKFiddle-Link

InnerVM.java
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;
}
}


inner.zul
<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>

OuterVM.java
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;
}

}


index.zul
<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.

link publish delete flag offensive edit

answered 2012-11-19 04:24:22 +0800

dennis gravatar image dennis
3679 1 6
http://www.javaworld.com....

updated 2012-11-19 04:25:42 +0800

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> 

use @init because it only loads once and never changes. (use @load is ok but more cost )
2. set the binding args in inner viewModel @init to the value of @ref
viewModel="@id('innerVM') @init('j17kiil$v2.InnerVM', theArg=passedText)"

3.change @ExecutionArgParam("passedText") to @BindingParam("theArg")

I know it is not so straightforward.

link publish delete flag offensive edit

answered 2012-11-19 08:18:33 +0800

cypha gravatar image cypha
27 1

Thank you very much, dennis! That is exactly what i was looking for. :)

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2012-11-16 21:16:53 +0800

Seen: 528 times

Last updated: Nov 19 '12

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More