-
FEATURED COMPONENTS
First time here? Check out the FAQ!
I really need help with the following scenario. We are migrating an application from MVC to MVVM and i think we are stuck. Any help would be much appreciated. Sample source code at the end of this message.
1. The main-view.zul contains a workspace Div.
2. The main-view creates the 'search-view.zul' with parent the workspace div.
3. The search-view sends the global command 'openDetailView' to the main-view.
4. The main-view detaches the search-view window and creates the 'detail-view.zul' with parent the workspace div.
5. The detail-view sends the global command 'reattachSearchView' to the main-view.
6. The main-view detaches the detail-view window and re-sets the search-view with parent the workspace div.
At this point the search-view.zul stops responding and sends all commands to the main-view generating the following message:
"cannot find any method that is annotated for the command close with @Command in MainViewVM"
I understand that the whole thing has to do with the lifecycle of each viewmodel's binder but i cannot find anything useful in the documentation.
The same functionality could be achieved easily using SelectorComposers and the old data binder.
The only alternative i have found is to make the windows visible/invisible instead of detach/setParent but this is not what we want.
<?page title="Main View" contentType="text/html;charset=UTF-8"?> <zk> <window id="winMainView" title="Main View" border="normal" height="100%" width="100%" apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('test.MainViewVM')" > <borderlayout> <north height="48px" border="none"> <vlayout> <label value="This is the Main View" /> </vlayout> </north> <center border="none"> <div id="divWorkspace" vflex="true" /> </center> </borderlayout> </window> </zk>
package test; import org.zkoss.bind.annotation.AfterCompose; import org.zkoss.bind.annotation.ContextParam; import org.zkoss.bind.annotation.ContextType; import org.zkoss.bind.annotation.GlobalCommand; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.select.Selectors; import org.zkoss.zk.ui.select.annotation.Wire; import org.zkoss.zul.Div; import org.zkoss.zul.Window; public class MainViewVM { @Wire private Div divWorkspace; /* * The window representing the 'search' sub-view */ private Window wSearchView; /* * The window representing the 'detail' sub-view */ private Window wDetailView; @AfterCompose public void init(@ContextParam(ContextType.VIEW) Component view) { Selectors.wireComponents(view, this, false); /* * create the search-view */ wSearchView = (Window) Executions.createComponents("/test/search-view.zul", divWorkspace, null); } @GlobalCommand public void openDetailView() { wSearchView.detach(); wDetailView = (Window) Executions.createComponents("/test/detail-view.zul", divWorkspace, null); } @GlobalCommand public void reattachSearchView() { wDetailView.detach(); wSearchView.setParent( divWorkspace ); } }
<?page title="Search" contentType="text/html;charset=UTF-8"?> <zk> <window id="winSearch" title="Search" border="normal" apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('test.SearchViewVM')" > <vlayout> <label value="This is the 'search' view embedded inside the main div" /> <button label="Close 'search' view and open the 'detail' view" onClick="@command('close')" /> </vlayout> </window> </zk>
package test; import org.zkoss.bind.BindUtils; import org.zkoss.bind.annotation.Command; public class SearchViewVM { @Command public void close() { BindUtils.postGlobalCommand(null, null, "openDetailView", null); } }
<?page title="Detail" contentType="text/html;charset=UTF-8"?> <zk> <window id="winDetail" title="Search" border="normal" apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('test.DetailViewVM')" > <vlayout> <label value="This is the 'detail' view embedded inside the main div" /> <button label="Close 'detail' view and try to re-attach the 'search view" onClick="@command('close')" /> </vlayout> </window> </zk>
package test; import org.zkoss.bind.BindUtils; import org.zkoss.bind.annotation.Command; public class DetailViewVM { @Command public void close() { BindUtils.postGlobalCommand(null, null, "reattachSearchView", null); } }
thanks to all
/costas
Use a `<include> in your workspace might solve your problem.
<include src="@load(vm.currentView)"/>
By changing the attribute vm.currentView
to search-view.zul
or detail-view.zul
, you can make components detach.
@hawk Thanks for your tip but the problem with this approach is that there is no state. Every time you are switching the "currentView" the related page will be reloaded.
I have to say that since the first post of this question we have built a small framework to handle efficiently these issues. In a few words, we are hiding the current window every time a new one is added to the 'workspace'. If the user closes the 'current' window, the main controller pops the previous window from the stack and changes its visibility to true again.
I think some kind of such a framework is still missing from the ZK core. I hope i will find the time to post a complete sample to the community although i think that most of the people here have already implemented some kind of solution.
/costas
Asked: 2012-12-20 11:54:46 +0800
Seen: 450 times
Last updated: May 27 '16
Databinding and auto-complete on combobox
Composite component and bind in ZK 6
Is there a way to resolve view model properties as input to client side javascripts?
How can I synchronize data in a ListBox in MVVM ? [closed]
MVVM Validator: class not found ? [closed]
How to Call Child ViewModel Method from Parent Window? [closed]
[Solved]Aplikasi Hibernate Spring [closed]
zk mvvm > what's the best component to make LOV (list of value) of a master data [closed]