# Conceptual question: trouble passing arguments

hkn
246 3

Hello all!

I am looking a convenience way to pass data to a window, I tried getArg() and getAttribute() and both
do not work, so I think I have misunderstood something
Currently my code to call a new window looks like this:

Window win = (Window) Executions.getCurrent().createComponents("mywin.zul", null, null);
win.setAttribute("data", someData ); // someData is not passed, see below "onCreate$myWin" // another guess was .... // Window win = (Window) Executions.getCurrent().createComponents("mywin.zul", null, sameDataAsMap); win.doModal(); // Or Popup or whatever... <window id="myWin" use="MyWinCrtl" ...> ..... </window> The attribute "use" is normally the only reference to java. So I have a nice and easy separation of view (zul files) and controller (java files). public class MyWinCrtl extends Window implements AfterCompose { protected Window myWin; public void onCreate$myWin(Event ev) {
doOnCreateCommon(myWin);
SameData someData = (SomeData) winEditCountry.getAttribute("data"); // and someData == null !!!
// Other way: HOW TO ACCESS THE ARG as ((CreateEvent)ev).getArg() does not work too!
// I NEED someData HERE !
// Everything else I do here works great !!

}
private void doOnCreateCommon(Window w) {
binder = new AnnotateDataBinder(w);
}
public void afterCompose() {
Components.wireVariables(this, this);
}
}

Because both approaches do not work here I make use of the session object to pass parameters.
That works! But from my point of view this is not a good solution.
If you detach the window the data object is still referenced and will not vanish until it is
explicit removed from the session whereas the attribute will be be destroyed with the window.
Further you have to pay attention not to get into conflict with the global (session based)
attribute names.

I hope someone has a nice solution ? !!

Thanks

/Horst

delete retag edit

## 11 Replies

ziccardi
321 7

Using

Window win = (Window) Executions.getCurrent().createComponents("mywin.zul", null, sameDataAsMap);

did you try
Map args = Executions.getCurrent().getArg();

?

Regards,
Massimiliano

cvarona
554 1 6

Hi,

why don't you enclose your window into a zk element so that you can write zscript both before and after its instantiation (the parameter map would be available in both of them), like this:

<zk>
<zscript>
arg.get( "some arg" );
...
</zscript>
<window ...>
</window>
<zscript>
arg.get( "some more arg..." );
...
</zscript>
</zk>

With kind regards

César Varona

hkn
246 3

@ziccardi,

Thank you and yes, I tried, but that does not work. The developers reference says clearly:

"Notice that arg is available only when creating the components for the included page, say my.zul.
On the other hand, all events, including onCreate, are processed later. Thus, if you want to
access arg in the onCreate's listener, use the getArg method of the org.zkoss.zk.ui.event.CreateEvent class."

So I think that is the reason. But there should be a way to get the arg.

I tried also to cast the Event ev to CreateEvent:

args = ((CreateEvent) ev).getArg()

But that results in an exception "org.zkoss.zk.ui.event.ForwardEvent cannot be cast to org.zkoss.zk.ui.event.CreateEvent"
That is because I like to use the GenericForwardComposer and the GenericAutowireComposer. And to make use of them both
I use

Components.wireVariables(this, this);

That is great and I love as I have to wire nothing and all works perfect!
Now I am just looking for an easier and secure way to pass parameters
to my components.

@César

Thank you, that would work, but I do not like to have any scripting in my views.
I use zkscript while prototyping. But when I develope the production version I avoid
it wherever it is possible.

Thank you, ziccardi & César

regards
/Horst

hkn
246 3

I FOUND IT, I have to follow the exception :-)

public void onCreate$myWin(Event ev) { doOnCreateCommon(myWin); ForwardEvent fe = (ForwardEvent) ev; CreateEvent ce = (CreateEvent)fe.getOrigin(); Map<String, MyData> args = (Map<String, MyData>)ce.getArg(); // args now holds the data !! } So it is as (almost) always: RTFM - Read The Fine Manual Those ZK gurus do a damned great job! Many thanks ! @ZK: wouldn't it be easier to deliver the original event, as here the CreateEvent. I think that would imporove the generic classes. Regards Horst answered 2008-11-17 13:52:09 +0800 ziccardi 321 7 Hi Horst. >wouldn't it be easier to deliver the original event, as here the >CreateEvent. I think that would imporove the generic classes. I don't agree. All events sent to methods event$componentId of composers are always ForwardEvent (they are "forwarded" to the composer).

Regards,
Massimiliano

hkn
246 3

Hi Massimiliano,

yes your are right! But my argument has nothing to do with the logical implementation.

The exiting benefit my use of Components.wireVariables(this, this);
Components.addForwards(this, this); is that it reduces my coding extremly in compare to the "old style" of databinding and event handling (in some cases more then 50%)! So if I code

onA_Event$a_Id( Event e) what would fullfill most people requirements in most cases? Specially in the case of onCreate$myWindow it was a pitfall to me. I now know to avoid it but it took me hours. I expected the e is of type CreateEvent, which was my fault. Now I will code onCreate\$id(ForwardEvent e) { e.getOrigin() .... }

Regards,
Horst

robertpic71
1275 1

>> @ZK: wouldn't it be easier to deliver the original event, as here the
>> CreateEvent. I think that would imporove the generic classes.

There is a finished Feature Request
to unrwrap Events.

But it seems this works only for Composer, not for the utils (autoforward..) within an extended GUI-Component.

/Robert

ziccardi
321 7

hmmm...
that will break all the code that actually use the forward event...

We use many many composer, it will be lot of time to fix all them.

Wouldn't be better to put a kind of configuration (for example, in the zk.xml file) where to enable/disable autounwrap (if you want to enable it by default, it's ok!) , for compatibility with the old code? Or use a different base class? Or implement an Interface (AutoUnwrapComposer)?

Please, don't break my code!! :-)

Regards,
Massimiliano

ziccardi
321 7

Shame on me. I've been too hurry.

If in my composer I leave onOk(Event evt) the event is not unwrapped.

Sorry for the useless post.

robertpic71
1275 1

In this thread we discuss this feature.

Here is henri's statement from the feature request:

public void onOK(KeyEvent event); //will unwrap ForwardEvent the forward event

public void onOK(Event event); //will not unwrap because we don't have enough information

public void onOK(ForwardEvent event); //will not unwrap because user request the ForwardEvent


/Robert

[hide preview]