# Very difficult to find a simple example of this common layout with MVVM

rickcr
704 7

In another post I'm trying to work on issues where I can differ rendering of my tab components, but fulfill isn't working since I'm often programmatically changing the selected tab. For example your on tab 2 and you click something and it then should switch to tab 3 (I can't get deferred rendering to work in this case.) More on it here http://www.zkoss.org/forum/listComment/20776/1/20

However it got me thinking, what if I didn't want to use tabs.. in fact I think I'm using tabs because I haven't found good examples using a MVVM orchestration of what I wanted.

Let's take it real simple...
I want:

1) A fixed header and/or footer
3) the main content area is where the content zuls should swap out when you click the different menu items

Each zul is backed by a View Model.

I do not want ANY of the zul's to be internally rendered UNTIL the user actually clicks on one of the menu links to open up the zul in the content area. (The View Model backing a zul obviously has a lot of db interaction of loads so don't want to unnecessarily call them.)

The above is very TYPICAL and yet I can't find an example of how to set this up? This should be one of the most common tutorials if one exists since it's your standard type of UIs. I've looked over the tutorial and the components http://www.zkoss.org/zkdemo/ but not seeing it.

Can someone help me out here and point me to an example of this typical UI menu based structure using an MVVM approach?

delete retag edit

## 4 Replies

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

http://emrpms.blogspot.in/search/label/ZK%20Layout

rickcr
704 7

Thanks Senthilchettyin, I opted for something similar after doing more research, but with a ViewModel that sits on top of the menu zul that acts like your democomposer class.

I'm wondering though is there a way to actually preserve the content so that if it was used once, it doesn't have to be recreated each time. For example right now my menu items call the following command with the page to load (think I got this example from terrytornado so instance names might look the same:)..

@Command
public void onShowContent(@BindingParam("param") String page) {
Include contentInc = (Include) Path.getComponent("/mainPage/inner");
contentInc.getChildren().clear();
Executions.createComponents(page, contentInc, null);
}


However this will always force a new composition of the page each time. Is there a way to preserve the old instance if it was already initialized once? Similar to how a tabbox with tabpanels works? Initially my plan was to just use a tabbox with the tabs having a false visibility. Flow to the different tabs happens by clicks triggered on the individual tabs themselves.

The PROBLEM with this though is what I posted about here http://www.zkoss.org/forum/listComment/20776/1/20 I can't seem to figure out a way to defer the loading of the tab content until its truly called upon.

Initially my plan was to just use a tabbox with the tab set to invisible, but since I can't get them to defer loading very easily I'm sort of stuck. I might have to go with some sort of solution terrytornado posted in the above link, modified to work in a view model command. I'll have to research how to create the tabpanel content on the fly, if it doesn't exist.

paowang
140 6

I wrote a example here:

ViewModel1.java
package jn312t1$v8;import org.zkoss.bind.annotation.Command;import org.zkoss.bind.annotation.NotifyChange;public class ViewModel1 { private boolean flag; public String getMessage() { return flag ? "page 1" : "page 1 hello"; } @Command(value = "toggle") @NotifyChange(value = "message") public void toggle() { flag = !flag; }} ViewModel0.java package jn312t1$v8;import org.zkoss.bind.annotation.Command;import org.zkoss.bind.annotation.NotifyChange;public class ViewModel0 {	private boolean flag;	public String getMessage() {		return flag ? "page 0" : "page 0 hello";	}	@Command(value = "toggle")	@NotifyChange(value = "message")	public void toggle() {		flag = !flag;	}}

page1.zul
<window border="normal" apply="org.zkoss.bind.BindComposer"	viewModel="@id('vm') @init('jn312t1$v8.ViewModel1')"> <button label="toggle" onClick="@command('toggle')" /> <label value="@load(vm.message)" /></window> page0.zul <window border="normal" apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('jn312t1$v8.ViewModel0')">	<button label="toggle" onClick="@command('toggle')" />	<label value="@load(vm.message)" /></window>

MyViewModel.java
package jn312t1$v8;import java.util.List;import org.zkoss.bind.annotation.BindingParam;import org.zkoss.bind.annotation.Command;import org.zkoss.bind.annotation.ContextParam;import org.zkoss.bind.annotation.ContextType;import org.zkoss.zk.ui.Component;import org.zkoss.zk.ui.Executions;import org.zkoss.zk.ui.select.Selectors;public class MyViewModel { private Component[] pages = new Component[3]; private int current = 1; @Command(value = "switchPage") public void switchPage(@ContextParam(ContextType.VIEW) Component view, @BindingParam(value = "page") int page) { if(pages[current] != null) pages[current].setVisible(false); current = page; if(pages[current] == null) { List<Component> list = Selectors.find(view, "#container"); pages[current] = Executions.createComponents("page" + current + ".zul", list.get(0), null); System.out.println("create new page: " + current); } pages[current].setVisible(true); } public String getTitle() { return "MVVM test"; }} index.zul <window title="@load(vm.title)" border="normal" width="600px" apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('jn312t1$v8.MyViewModel')">	<menubar>		<menuitem label="page 0"			onClick="@command('switchPage', page=0)" />		<menuitem label="page 1"			onClick="@command('switchPage', page=1)" />	</menubar>	<div id="container" width="500px" height="500px" /></window>

Hope this helps.

rickcr
704 7

Awesome stuff paowang!

This is helping tremendously! Thanks for taking the time to write such a detailed example. This should be in a wiki or blog somewhere. Great job.

[hide preview]