# how do i load a list of objects in a view model and display it in another zul?

boskonovic
46 1

I'm newbie with zk6 and i'm trying to implement a search method in my ViewModel class. in this method i want to load a list of objects and navigate to another page where i can display the list. I managed to load data and display it in the seach.zul but i couldn't display my list of objects in another(result.zul) page.

@Command
@NotifyChange({ "searchBean", "slides" })
public void doSearch() {

slides = new ListModelList<SlideBean>(data.getSlides());
Executions.sendRedirect("/wam/ais/slides/checkout/result.zul");

}



this is the result page:

<?page title="slides" contentType="text/html;charset=UTF-8"?>
<zk>
<window id="w_slides" title="SLIDES" border="normal"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('eu.dedalus.dia.ais.slides.checkout.ui.SearchVM')">

<vbox>
<style>
.hb{ float:right; }

</style>
<hbox sclass="hb">

<button label="INDIETRO" />
<button label="ESEGUI" />
</hbox>

<checkbox />
<template name="model" var="slide">
<listitem>
<listcell>
<checkbox />
</listcell>
<listcell label="#" />
</listitem>
</template>

</listbox>

</vbox>

</window>
</zk>



delete retag edit

## 12 Replies

Senthilchettyin
2625 3 8
http://emrpms.blogspot.in...

You can check an example here

ajvan
48

Try something like this:

Put this peace of code before you call Executions.sendRedirect:

Map<String, Object> args = new HashMap<String, Object>();
args.put("slides", slides);
BindUtils.postGlobalCommand(null, null, "setSlides", args);


and in the SearchVM define a new method with:

@GlobalCommand("setSlides")
public void setSlides(@BindingParam("slides")  ListModelList<SlideBean> newSlides) {
slides = newSlides;
}


You post a global command which is a way for communication between two ViewModels, and you pass a datastructure as a parameter.

I didn't test it, but I think it would work. :)

and here

Cheers,
Ivan

ajvan
48

http://books.zkoss.org/wiki/ZK%20Developer's%20Reference/MVVM/Data%20Binding/Global%20Command%20Binding

http://books.zkoss.org/wiki/ZK%20Developer's%20Reference/MVVM/Syntax/Data%20Binding/@global-command

boskonovic
46 1
Thank you for your quick answer. I tried the solution you mentioned with no success. I decided to test the GlobalCommand thing with a smaller code. the first ViewModel:
public class TestVM {

@Command
public void testGC(){

Executions.sendRedirect("/wam/ais/slides/checkout/test2.zul");

}

}

the second ViewModel:
public class TestVM2 {

@GlobalCommand
public void global(){

System.out.println("global");

}

}

and my zul pages:
<zk>
<window title="test1" border="normal"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('ui.TestVM')">
<button label="btn" onClick="@command('testGC') @global-command('global')"/>
</window>
</zk>


<?page title="test2" contentType="text/html;charset=UTF-8"?>
<zk>
<window title="test2" border="normal"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('ui.TestVM2')">
New Content Here!
</window>
</zk>


i also tried to call the global command using using BindUtils :
BindUtils.postGlobalCommand(null, null, "global", null);

does any one know if i did something wrong? or may be i'm not understing the GlobalCommand feature at all.

ajvan
48

You need to annotate the GlobalCommand since you can have more than one. So use @GlobalCommand("CommandName")

boskonovic
46 1

I added the annotation @GlobalCommand("global") but that didn't help.

rdgrimes
735 7

Seems to me your global command didn't work because, before it's executed out of the first zul, it does a redirect that passes control to a second zul. So, the global command never gets executed.

But, here's a couple methods that I have used, in an MVVM, to make data accessible from one zul to another.

Method 1: bind both zul's to the same instance of the viewmodel. Because each zul @init will actually create a new instance of the viewmodel, they cannot possibly share data across viewmodel instances. But, you can do what I have done, which is to @init each zul to a viewmodelproxy, which turns around and calls a shared common viewmodel. See my "workaround" here: http://tracker.zkoss.org/browse/ZK-1077

Method 2: The data produced from zul 1's viewmodel can be stored as a session attribute and then retrieved by zul 2's viewmodel. See Sessions.getCurrent().setAttribute()

Method 3: Publish the data from zul 1's viewmodel into an EventQueue, and then subscribe to it in zul 2's viewmodel. Obviously, this means both zuls must be created and @inited before pushing the data out of zul 1's viewmodel and into the EventQueue. In other words, if you create zul 2 (the result zul) subsequent to zul 1's (the search), it probably won't work.

bozo
24

Hi rdgrimes ,

I need exactly the same thing, only the use case is that I have several application "screens" (ZULs binded to a same VM).

What is the proper way of doing this, except your "hack"? To use MVC pattern instead of MVVM?

Using one ZUL where all the "screens" are defined and then navigating between them using the API (thus the parent VM is always the same)?

I'm also new to ZK, and this question is more for the more seasoned folk here.

boskonovic
46 1

@rdgrimes for now i used the solution given in the example of Senthilchettyin. But your methods look very interesting. i'll give them a try for sure.
thank you

ntsetso
59 1 4

Hi,

I'm also a newbie and with a similar issue.
I have a Form1 in page1.zul bound to VM1 and a Form2 in page2.zul bound to VM2. Page2.zul will open after a user inputs some text in Form1 and clicks a submit button.
The user inputted data is passed to VM2 to fetch some records from a database and then the result is displayed in page2.zul's Form2 when it opens. Database is editable from page2.zul.

I understand how to do this if both forms are opened in the same page, which means that VM1 and VM2 are initiated the same time. However in my case I'd like Form2, i.e., page2.zul to be displayed only after user confirmation.

I had already developed a similar approach to Senthilchettyin, using a POJO to temporarily store user inputted data, which I thought could bring up concurrency issues.
I can see that Senthilchettyin's solution is more sophisticated and more elegant than mine.

Would like to try rdgrimes's solution which unfortunately I didn't understand.

@boskonovic Did you ever try? If some one did please post your example.

@rdgrimes Will you please elaborate you solution with a small example for a newbie?

TIA,
ntsetso

[hide preview]