zk

Combining ZUML EL Expression with Binding


There is two different usages of EL constructs in ZK. One for page construction (ZUML) and one for binding. I understand that the former is evaluated before the latter and so one has to be careful mixing them. However, it seems it should be possible to use ZUML EL to construct binding expressions. Specifically, I would like to make something like this work:

<vbox vflex="1" viewModel="@id('vm')@init(arg.viewModel)"
    hflex="1" style="margin-top:1em">
    <zk forEach="${vm.indexes}">
        <button label="Button ${each}"  onClick="@command(vm.click(${each}))" />
    </zk>
</vbox>

where indexes is, say, 0...4. It should render 5 buttons "Button 0" to "Button 4" and when clicking on a button the click method on the view model would be called with the corresponding integer.

enter image description here

When trying however I get org.zkoss.zel.ELException: Failed to parse the expression [${vm.click(${each})}].

The problematic part is the bind expression in onClick. Leaving that out gets me the buttons, so that the actual iteration on construction works, I just cannot the the binding expression generated.

Thanks for helping!!


Solution

  • This is because the "each" variable from EL is only available during the component creation phase,

    While data binding is parsed during the event phase, meaning that EL variables like "each" are not accessible at that time.

    If you want to differentiate each button's calling, please change to use <forEach> component and create a common command like @command("invokeMethod") and pass a parameter.

    For example:

    <forEach items="${vm.indexes}">
        
    <button label="Button ${each}" onClick="@command('invokeMethod', param=each)"/>
    
    </forEach>
    

    Thanks