EL in a forEach @command not working?

asked 2013-03-09 02:05:31 +0800

rickcr gravatar image rickcr
704 7

Normally I use a VM for most things, but I'm messing around with also using some Composers for some separation of concerns.

I'm playing around with having a Composer generate a list of reports dynamically that the user can click on. When they click on one of them I'd like the outer ViewModel to pick up to the clicked event, not the Composer so I thought something like this would work:

<window border="none" apply="org.zkoss.bind.BindComposer"  id="mainWindow"
    viewModel="@id('vm') @init(menuVM)" >

    <west border="none">
            <vlayout id="reportsMenu" apply="${reportsController}">
                <zk forEach="${reportsMenu$composer.reports}">
                    <a label="${each.name}"  onClick="@command('onShowItemPage', page='${each.code}')" />

The issue is the EL of ${each.code} is being evaluated literally within the @command instead of resolving to the 'code' property of 'each'

I'm guessing I can't use @command within this type of construct? I suppose the pure approach is to fire an onClick event and then send out a global event that the menuVM would listen to.

delete flag offensive retag edit

2 Answers

Sort by ยป oldest newest most voted

answered 2013-03-11 02:46:35 +0800

dennis gravatar image dennis
3669 1 6

mixing MVC + MVVM will have timing issue, basically zul EL are processed when creating and MVVM is doing magic in afterCompose(by parsing the annotation)

in original case, each in forEach EL is only available when creating (in forEach loop, the components are created before afterCompose) and it will not store in anywhere, so even in MVC , you have to use custom-attribute to keep the 'each' at somewhere for accessing it later.

same idea in mvvm. you have to store it and access it later , I think you can try this (not sure, I didn't have code to try).

<zk forEach="${reportsMenu$composer.reports}">
    <a label="${each.name}"  onClick="@command('onShowItemPage', page=myValue)" />
        <custom-attributes myValue="${each.code}"/> 

P.S, 'each' in children-binding and collection-bindiing(model+teamplate) are different from forEach case, it handles/stores the 'each'(just same name in forEach case) so you can access it directly in binding syntax

however, I still don't like this kind of mixing, use global-command is more clean.

link publish delete flag offensive edit


(note: I'll be marking this as the correct answer, but I don't want it to appear answered just yet since I'm still curious now about how to get this click to be picked up in a composer vs the view model. I know it's sort of a different question, but would like it in this thread.)

rickcr ( 2013-03-11 15:35:45 +0800 )edit

answered 2013-03-09 16:46:59 +0800

rickcr gravatar image rickcr
704 7

updated 2013-03-11 15:32:33 +0800

NOTE: why do comments only allow so few characters? I want to follow up to my original without actually answering the question, but because the comments only allow about 300 characters that's not much.

Anyway, how would one even create an onClick handler dynamically like that to be picked up in one's composer? I'm trying to be well-rounded in my ZK knowledge and I'd like to know how to do this 'without' using a VM?

So for example, I read you don't have "each" within a even listener so you have to create a custom attribute.. but how would you know how to get the attribute when the components are created dynamically? You can't really wire them up in your composer?

How could I get access to "each.code" in a click listener in my Composer? I can't really get the component by id since I the number of href components is dynamic...

   <zk forEach="${reportsMenu$composer.reports}">
        <a label="${each.name}"  onClick="openReport">
            <!-- I need this each.code value in Composer onClick ! -->
            <custom-attributes myValue="${each.code}"/> 

Note I wanted to do ...

   <zk forEach="${reportsMenu$composer.reports}">
        <a label="${each.name}"  onClick="openReport(${each.code}"/> 

EDIT 3/11

per @Dennis solution:

  <a   label="${each.name}"  onClick="@command('onShowContent', page=myValue)">
       <custom-attributes myValue="${each.code}"/>

The solution worked PERFECTLY for calling the outer VM, but I agree this is sort of messy.. sending of a global command from the composer would be better.

So that being said, How would you do this in the classic MVC approach? How do I notify an onClick in my composer when I can't give the onclick an id, since the links/button are created on-the-fly? Do I need to use a script in my onclick that sets a hidden variable and then fire off some sort of click event in the zscript for the composer to bind to?

For example the theory is I'd want to get a click handle in my composer to read

       <zk forEach="${reportsMenu$composer.reports}">
             <a label="${each.name}"  onClick="openReport(myValue)">
             <custom-attributes myValue="${each.code}"/>

But I'd need an @Listen in my Composer that could listen for this, but I can't give it an id since it won't be unique. Javascript could get the openReport with the page value just fine, but now I have to still send that to the composer from javascript?

link publish delete flag offensive edit


Did you ever follow any Standard Forum like Stackoverflow ? Please see there . Also you can edit your question rather than asking question in answer section.

sjoshi ( 2013-03-11 06:02:38 +0800 )edit

just bumping based on my EDIT above. On how to handle an onclick in a composer based on the dynamic generation of links.

rickcr ( 2013-03-13 18:08:51 +0800 )edit

Did you used Listner?

sjoshi ( 2013-03-13 18:29:58 +0800 )edit

@Sjoshi, when you say "did I use Listener" - do you mean annotate a method in my controller with @Listen(...)? .. that's the issue I'm not sure how to bind the annotation since I only see examples of binding the onClick by id which I can't use in this case. (eg @Listen("onClick = button#someId")

rickcr ( 2013-03-13 19:53:45 +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




Asked: 2013-03-09 02:05:31 +0800

Seen: 116 times

Last updated: Mar 11 '13

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