-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Is it possible to access the composer applied on a widget, given the widget's ID?
I created a simplified program below to illustrate my case:
-------------------------------------------------------------
<window id="mywindow" apply="MyComposer">
<button onClick="mylabel.value=mywindow.getComputedData()" />
<label id="mylabel" />
</window>
--------------------------------------------------------------
public class MyComposer extends GenericForwardComposer {
public Object getComputedData() {
return "My computed data...";
}
}
--------------------------------------------------------------
For the MVC reason, I put all controller logic in MyComposer. Inside the Button's onClick event handler, I have a trouble invoking the method defined in MyComposer.
I know that
1) If I move my controller logic to a Window subclass and use it by the "use" attribute on Window, the above code will work. But I don't want to put the non-ui logic in a window ui subclass.
2) We can apply multiple composers to the window component. My code above is not sufficient to identify which composer in the list to invoke.
3) Inside the button's onClick event handler, I can do Events.postEvent() to invoke method in MyComposer. However, I need an immediate returned value to do some more UI logic.
Is possible to access a composer?
Thanks in advance!
windeyu
You can follow this tutorial to move your event listener to composer instead of scatter them in the view.
/robbie
Hi robbiecheng,
Your suggestion is absolutely right in my simplified case that merely illustrated my question. Here is my real complicated case.
I defined two macro components, say A and B, that each contains windows, trees, buttons, listbox, etc. And both A and B have composers applied to the top-level window. The component A can control the component B. For example, the selection of a drop-down list in marco A can load the view in B. The view in B can be edited by user. The component A has button to save the view of B into the database.
The event handlers for the component A are methods defined on A's composer. The view state of the component B can be obtained from a method on B's composer. When the event handlers on A's composer (such as button click) is invoked, I can't figure out a way to call methods on B's composer.
What's your suggestion?
Thanks again.
-windeyu
you can use Events.sendEvent(Component comp, Event event) to post events to B.
and using Path utility to target window component on B.
http://www.zkoss.org/javadoc/3.6.1/zk/org/zkoss/zk/ui/Path.html
/robbie
public class MyComposer extends GenericForwardComposer { public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); comp.setVariable("ctl", this, true); } public Object getComputedData() { return "My computed data..."; } }
<window id="mywindow" apply="MyComposer"> <button onClick="mylabel.value=ctl.getComputedData()" /> <label id="mylabel" /> </window>
Hello!
I read robbies suggestion and must say that this will not work in special circumstances!
What if I do not know the component where I should post the message to?
In my opinion a component used as a macro should work on its own so that I can use it without knowing ids of Compononents in its parent. Otherwise a macros does not make sense for me.
If I use macro components with ForwardComposer I would like this macro to send events to its above Composer.
Same in other way. In my opinion the goal should be that I get messages from A and send messages to without knowing anything about ids or something else in the subcomponents.
Is there a solution for this?
>In my opinion a component used as a macro should work on its own so that I can use it without knowing ids of Compononents in its parent. Otherwise a macros does not make sense for me.
Outside of the Macro component, this sounds reasonable.
The question is really on how the one design the macro component encapsulate these "subcomponents". We have not found a better way other than writing a Java class that extends the HTMLMacroComponent and handle the encapsulation. However, since 5.0.4, by default, HTMLMacroComponent will supports auto forward events and wire accessible variables from "subcomponents" to your macro component, so it is much easier to implement such encapsulation than before.
Or maybe you have some better idea?
you can reach the use class from the the composer (apply) by cast,
so put the composer in the use class if you want to seperate View from Control.
for me the following works:
<window
use="MyComponentWindow "
apply="MyComponent">
<button id="a"/>
</window>
create a composer member in the use class and a setter
public void MyComponentWindow.setComposer(MyComponent composer){this.composer = composer};
do this:
public class MyComposer extends GenericForwardComposer {
public Button a;
MyComponentWindow myComponentWindow;
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
myComponentWindow=(MyComponentWindow)comp;
myComponentWindow.setComposer(this);
}
Asked: 2009-05-30 01:19:45 +0800
Seen: 858 times
Last updated: May 10 '12