0

Path.getComponent from a nested component can't get handle?

asked 2013-02-13 15:47:02 +0800

rickcr gravatar image rickcr
704 7

updated 2013-02-13 16:15:40 +0800

I have a menu on a main layout page. The MenuVM is responsible for creating the page and adding it to one of the div sections on the main layout. This works just fine. No problem.

However, one of the pages that could be added, needs to also add a different zul within in it (add to a div) depending on one of the main menu subitems selected.

The issue is that for some reason, trying different paths, I can not get access to the div component that I want to add content to within this nested zul.

I think a picture will help:

http://tinyurl.com/aqje3ro

Looking at that picture how would I get a handle to the component:

/pageOne/pageOneContent ?

I would have thought the following would work just fine, since it works just fine following the pattern on the main layout:

Component comp = Path.getComponent("/pageOne/pageOneContent ");

//I even tried tracing back up to the main layout and working back down but not having luck there either:

Component comp = Path.getComponent("//mainContent/contentSection/serviceHolder/serviceContent");

Am I doing something wrong? There needs to be a way to handle this?

Digression: one of my small complaints with Zk is that it makes using a "layout" is very difficult. Seems to be a lot of ugly plumbing in involved. It would be nice if ZK took the tab toolbar concept a bit further and could apply that to layouts that weren't tabpanels. For example you click an href or menu item and you could target a section of your layout/template to be populated, without having to go through the issues of using Executions.createComponents. There is the added complexity as well of whether you always want a new instance created of the backing VM or if you want to reuse the existing one. I'd like to see something like...

<menuitem target="pageSectionId" src="somePage.zul" useexisting="yes" label="Some Page"/>

delete flag offensive retag edit

4 Answers

Sort by » oldest newest most voted
0

answered 2013-02-14 08:31:00 +0800

rickcr gravatar image rickcr
704 7

I'm starting to think maybe using zkspring 3.1 is the culprit?

It's so odd, I can do things in zkfiddle http://zkfiddle.org/sample/245i7ff/14-Nested-getComponent-issue and things work just fine as expected.

The main difference between zkfiddle and my app is the use of zkspring. I even upgraded to 6.5.1 (from 6.5) thinking that might be the cause and same issues.

Here is another thing odd, in zkfiddle I can go right after the component with "/divIdValue" eg Component comp = Path.getComponent("/contentSection");

YET, in my application, which seems like practically identical code I have to first at least provide the parent window id in order to get to a child eg: Component comp = Path.getComponent("/mainWindowID/contentSection");

I'll try to work up a demo app with spring and without to verify if that's somehow the cause.

link publish delete flag offensive edit
0

answered 2013-02-14 15:40:23 +0800

rickcr gravatar image rickcr
704 7

updated 2013-02-14 15:43:09 +0800

I'm just really stumped on this.. it's not a spring thing somehow fiddle can get components nested differently than I seem to be able to do. Maybe something do with the wildcard package name. No idea. Regardless, I just want to get these stupid selectors working (can you tell I'm frustrated:) Wasting too much time on this.

I have a war you can download to see the issue https://dl.dropbox.com/u/86998/zkTestGetComponent.war and here is the source code that should build fine with maven  https://dl.dropbox.com/u/86998/zkTestGetComponent.zip

Here is the source code of what I'm trying to do:

Index zul and its VM

<?page title="ZK TestGetComponent" id="mainPage"?>
<zk>    
    <window border="none" apply="org.zkoss.bind.BindComposer"  id="mainWindow"
        viewModel="@id('vm') @init('net.reumann.zktesting.OuterVM')" width="100%" height="100%">

        <borderlayout height="100%">
            <north border="none">
            </north>
            <center border="none">
                <vlayout>
                    <div height="100%" width="100%" id="contentSection"  />
                </vlayout>
            </center>           
        </borderlayout>
    </window>
</zk>

public class OuterVM {
    private final static Logger logger = LoggerFactory.getLogger(OuterVM.class);

    @AfterCompose
    public void doAfterCompose() { 
        //in fiddle I can just use:
        //Component comp = Path.getComponent("/contentSection");
        Component comp = Path.getComponent("/mainWindow/contentSection"); 
        Executions.createComponents("/pages/content_one.zul", comp, null);
    }
}

content_one.zul and its VM and the zul it should be loading into the UI:

<zk>
  <window border="normal" apply="org.zkoss.bind.BindComposer"
    viewModel="@id('vm') @init('net.reumann.zktesting.ContentOneVM')">

    <div>Content One (you should see Inner Content below this, but not working)</div>
    <div id="innerSection"></div>
  </window>
</zk>

public class ContentOneVM {
    @AfterCompose
    public void doAfterCompose() {
        //this I'd think should work but doesn't...
        //Component comp = Path.getComponent("//mainPage/mainWindow/contentSection/innerSection");
        //this not working either
        Component comp = Path.getComponent("/innerSection");
        Executions.createComponents("inner_content.zul", comp, null);
    }
}

//VM should load this :

<zk>
  <window border="normal">
    <div>Inner Content</div>
  </window>
</zk>

Not sure why I'm having such difficulty with this? Loading up content into the UI I would think would be a common aspect of UI development.

link publish delete flag offensive edit
0

answered 2013-02-14 16:04:44 +0800

terrytornado gravatar image terrytornado flag of Germany
9393 3 7 16
http://www.oxitec.de/

Hi, attached an utility class for showing the complete component tree. So you can see i.e. what is exactly the first component that you searched.

best Stephan

/**
 * Copyright 2010 the original author or authors.
 * 
 * This file is part of Zksample2. http://zksample2.sourceforge.net/
 *
 * Zksample2 is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Zksample2 is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Zksample2.  If not, see <http://www.gnu.org/licenses/gpl.html>.
 */
package de.forsthaus.util;

import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.zkoss.zk.ui.AbstractComponent;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Components;

/**
 * Helper class for showing the zkoss component tree in the console for a root
 * component. <br>
 * <br>
 * 
 * <pre>
 * Call: System.out.println(ZkossComponentTreeUtil.getZulTree(aComponent));
 * </pre>
 * 
 * @author bbruhns
 * 
 */
public class ZkossComponentTreeUtil {

    final private static class FieldListener implements IAddListener {
        private final Field field;

        FieldListener(Field field) {
            super();
            this.field = field;
        }

        @Override
        public void addListener(Component component, StringBuilder result, int depth) {
            try {
                Map<?, ?> m = (Map<?, ?>) field.get(component);
                if (m != null && !m.isEmpty()) {
                    for (Map.Entry<?, ?> entry : m.entrySet()) {
                        result.append(StringUtils.leftPad("", depth << 2) + "  " + entry.getKey() + " -> " + entry.getValue() + "\n");
                    }
                }
            } catch (IllegalArgumentException e) {
            } catch (IllegalAccessException e) {
            }
        }
    }

    private interface IAddListener {
        void addListener(Component component, StringBuilder result, int depth);
    }

    final private static IAddListener ADD_LISTENER;

    static {
        IAddListener tmp = null;
        try {
            final Field field;
            field = AbstractComponent.class.getDeclaredField("_listeners");
            field.setAccessible(true);
            tmp = new FieldListener(field);
        } catch (SecurityException e) {
        } catch (NoSuchFieldException e) {
        }

        if (tmp == null) {
            tmp = new IAddListener() {
                @Override
                public void addListener(Component component, StringBuilder result, int depth) {
                }
            };
        }

        ADD_LISTENER = tmp;
    }

    static public CharSequence getZulTree(Component component) {
        return new ZkossComponentTreeUtil().getZulTreeImpl(component);
    }

    private ZkossComponentTreeUtil() {
        super();
    }

    private CharSequence createCompName(Component component) {
        StringBuilder sb = new StringBuilder();
        sb.append(component.getClass().getSimpleName());

        String id = component.getId();
        if (!Components.isAutoId(id)) {
            sb.append(" id=\"" + id + "\"");
        }
        return sb;
    }

    private CharSequence getZulTreeImpl(Component component) {
        if (component == null) {
            return "Component is null!";
        }

        StringBuilder result = new StringBuilder(6000);
        return getZulTreeImpl(component, result, -1);
    }

    @SuppressWarnings("unchecked")
    private StringBuilder getZulTreeImpl(Component component, StringBuilder result, int depth) {
        ++depth;
        CharSequence id = createCompName(component);
        if (CollectionUtils.isEmpty(component.getChildren())) {
            result.append(StringUtils.leftPad("", depth << 2) + "<" + id + " />\n");
            return result;
        }

        result.append(StringUtils.leftPad("", depth << 2) + "<" + id + ">\n");

        ADD_LISTENER.addListener(component, result, depth);

        for (Iterator iterator = component.getChildren().iterator(); iterator.hasNext();) {
            getZulTreeImpl((Component) iterator.next(), result, depth);
        }

        result.append(StringUtils.leftPad("", depth << 2) + "<" + component.getClass().getSimpleName() + " />\n");
        return result;
    }

}
link publish delete flag offensive edit
0

answered 2013-02-14 16:58:41 +0800

rickcr gravatar image rickcr
704 7

WOW. I think I found a solution yet still don't understand it. Major confusing especially since I wasn't see the same thing using zkfiddle (anyone know why things would be different there using Path.getComponent?)

Apparently Window changes the id space? I didn't see that in the docs though, I only say "page" changes the id space? So if I modify the above "contentOne.zul" to not use a window but instead something like a layout:

<zk>
  <vlayout  apply="org.zkoss.bind.BindComposer"
    viewModel="@id('vm') @init('net.reumann.zktesting.ContentOneVM')">

    <div>Content One (you should see Inner Content below this, but not working)</div>
    <div id="innerSection"></div>
  </vlayout>
</zk>

I could now get it to work by using:

Path.getComponent("//mainPage/mainWindow/innerSection")

BUT, although that works, I have not idea why if it does use a new Window and thus a new id space, why I can't access the resource via:

Path.getComponent("/innerSection") ?

link publish delete flag offensive edit

Comments

Window component does implement IdSpace interface. Check the javadoc.

vincentjian ( 2013-02-21 03:43:08 +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
1 follower

RSS

Stats

Asked: 2013-02-13 15:47:02 +0800

Seen: 62 times

Last updated: Feb 14 '13

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