0

How to pass value between two include child pages and ViewModels

asked 2018-06-12 18:04:50 +0800

matthung gravatar image matthung
3 2

updated 2018-06-12 18:05:10 +0800

The situation is I have two child pages A and B, A is the query page, B is edit page.

After clicking search button on A page, it will generate query results as grid, and each row of grid have edit button, if I click the edit button of that row, the A page will change to B page for editing the data of that row. The problem is both pages are child page included in a main page, does anyone know how to achieve this?

delete flag offensive retag edit

Comments

Getting main page's <include> component in inner1.zul's ViewModel and reset its src value to inner2.zul

matthung ( 2018-06-13 09:34:18 +0800 )edit

3 Answers

Sort by » oldest newest most voted
0

answered 2018-06-19 20:26:47 +0800

cor3000 gravatar image cor3000
4143 1 7
ZK Team

the most basic way is to send a @global-command to the main viewmodel which then can update the url of the include:

in main.zul

<div viewModel="@id('vm') @init('my.org.MainViewModel')">
  <include data="@load(vm.navigationData)" src="@load(vm.currentViewUrl)"/>
</div>

in main view model

public class MainViewModel {
    ...
    @GlobalCommand
    public void editPerson(@BindingParam("person") Person person) {
        this.data = person;
        this.currentViewUrl = "/person/edit.zul"
        BindUtils.postNotifyChange(null, null, this, "data");
        BindUtils.postNotifyChange(null, null, this, "currentViewUrl");
    }
    ...
}

trigger the global command from anywhere else

e.g. from a zul file in a grid

<template name="model">
    <row>
        ...
        <cell>
            <button label="edit" onClick="@global-command('editPerson', person=each)"
        </cell>
    </row>
</template>

or the same from java code

BindUtils.postGlobalCommand(null, null, "editPerson",
                            Collections.singletonMap("person", clickedPersonObject))

If this doesn't match your scenario please provide a runnable example on zkfiddle.org then I can add what's missing to help in your specific case.

link publish delete flag offensive edit
0

answered 2018-06-20 09:30:59 +0800

matthung gravatar image matthung
3 2

@cor3000, thanks for your response, finally I solved as below.

main.zul

<zk>
<window>
    <include id="include" src="/inner1.zul"/>
</window>
</zk>

inner1.zul

<zk>
    <div apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('idv.matt.vm.Inner1VM')"> 
        <button label="To inner2" onClick="@command('toInner2')"/>
    </div>
</zk>

Innver1VM.java

public class Inner1VM {

    @Command
    public void toInner2(@ContextParam(ContextType.PAGE) Page page) {
        // get root component from Page,then use Component.query() get get <include> by id
        Include include = (Include) page.getFirstRoot().query("#include");
        include.setSrc("/inner2.zul"); // change 

    }

}
link publish delete flag offensive edit

Comments

technically you can access the components directly like that and if it's ok with you then I don't see a problem. It's just not clean MVVM anymore but who I am I to decide what's "clean" and what's "dirty" ;)

maybe try http://books.zkoss.org/zk-mvvm-book/8.0/syntax/selectorparam.html instead

cor3000 ( 2018-06-20 10:13:07 +0800 )edit

And with the global-command it's not even needed to query the component

chillworld ( 2018-06-20 11:23:00 +0800 )edit
0

answered 2018-06-20 12:21:26 +0800

matthung gravatar image matthung
3 2

updated 2018-06-20 13:16:07 +0800

Hi all, thanks for your comments, finally change as below

main.zul

<zk>
<window viewModel="@id('vm') @init('org.my.MainVM')>
    <include id="include" src="@load(vm.currentUrl)" data="@load(vm.data)"/>
</window>
</zk>

MainVM.java

public class MainVM {

    private String currentUrl;
    private Object data;

    @GlobalCommand
    // @NotifyChange({"currentUrl", "data"}) // potential execution notify order issue, please see cor3000's comments below
    public void changeIncludeUrl (@BindingParam('url') String url ,
                                    @BindingParam('person') Person person) {
        currentUrl = url;
        data = employee;
        BindUtils.postNotifyChange(null, null, this, "data"); // make sure the NotifyChange order
        BindUtils.postNotifyChange(null, null, this, "currentUrl");
    }

    // getter and setter    
}

person.zul (inner1)

<zk>
    <div viewModel="@id('vm') @init('org.my.vm.PersonVM')"> 

        <grid model="@load(vm.personList)">
            ...
            <template name="model">
                ...
                <button label="Edit" 
                        onClick="@global-command('changeIncludeUrl', url='/edit.zul', person=each)"/>
                ...
            </template>
        </grid> 
    </div>
</zk>

PersonVM.java (Inner1VM)

public class PersonVM {

    private List<Person> personList;
    ...
    // getter and setter    

}

PersonEditVM.java (Inner2VM , edit.zul's viewModel)

public class PersonEditVM {

    private editPerson;

    @Init
    public void init(@ExecutionArgParam("data") Object data) {
        editPerson = (Person) data;

    }
    // getter and setter    
}
link publish delete flag offensive edit

Comments

be careful with the notify change order... if the "currentUrl" changes before the "person" parameter it will load the contents with the previous person. that's why I put the notifychanges programmatically in that particular order

cor3000 ( 2018-06-20 12:41:08 +0800 )edit

if you are using ZK-EE you can use the <apply> shadow element which changes the templateURI after setting additional parameters (http://books.zkoss.org/zk-mvvm-book/8.0/syntax/apply.html) so you don't have to care about such details

cor3000 ( 2018-06-20 12:43:35 +0800 )edit
Your answer
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
2 followers

RSS

Stats

Asked: 2018-06-12 18:04:50 +0800

Seen: 27 times

Last updated: Jun 20

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