You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Robert <rv...@xs4all.nl> on 2005/06/30 09:33:16 UTC

Binding confusion

Hi!
I am having some questions regarding to bindings.

I have a component with one parameter which is a complex object that 
includes some setters. I have set the direction to custom. I have done 
it because I need to access it before the render phase. And also because 
I can implement the methods to access the parameter myself and avoid to 
use abstract classes (bad design in my opinion).

Anyway the confusion is that each time I call getBinding().getObject() I 
noticed that I get an object with a different address. They do have the 
correct values set by the page that created this parameter. However if I 
call a setter on the parameter this change has dissapeared the next time 
I call getBinding().getObject().

I have avoided this problem by using an instance field with the 
parameter type and set it the first the the parameter is accessed. This 
works fine for the pre-render and render phase.

The problem I am having now is with the combination of cleaning up the 
parameter and making changes available in an action (long after the 
render has finished).

Maybe a little bit of pseudo-code will make things more clear want I 
would like...

*Code:*

private MyObject param;
private MyObject getParam()
{
    if (param == null)
        param = getBinding().getObject();
    return param;
}

protected renderComponent()
{
    getParam().setValue(1);
    ....
}

public action()
{
    int x = getParam().getValue();
}



My questions are:
1) Is it possible to keep the update in the object without having an 
instance variable?
2) How and when can I cleanup the instance variable (set it to null)? If 
I do it in cleanupAfterRender it means that the update is not available 
in the action handler.
3) Will the component object that is used for the action not always the 
same object used to render? And therefore instance variables should not 
be trusted between those phases?

Any background information related to these topics is very welcome to 
increase my knowledge about Tapestry.

TIA!
Robert.

Re: Binding confusion

Posted by Kent Tong <ke...@cpttm.org.mo>.
Robert <rvlwork <at> xs4all.nl> writes:

> It seems my questions are not answered on both the mailing list and 
> forum which makes me worry about continuing to use tapestry.
> I am curious why not. Is it because
> 1) The question is too difficult
> 2) This has been asked many times before and people are bored to answer 
> it again
> 3) My question is not formulated correctly and therefore incomprehensible
> 4) Something else

What you're describing is weird and cannot be explained normally. 
So something else must be wrong. I've written a simple program
that does what you're trying to do and it works fine. So, you
may compare it to yours to see what's wrong.

Home.html:
<form jwcid="@Form" listener="ognl:listeners.onSubmit">
<span jwcid="@Comp" param="ognl:foo"/>
<input type="submit"/>
</form>

Home.page:
<page-specification class="helloworld.Home">
    <property-specification name="foo" type="helloworld.Foo" persistent="yes"
initial-value="new helloworld.Foo()"/>
</page-specification>

Home.java:
public class Home extends BasePage {
	public void onSubmit(IRequestCycle cycle) {
		Tapestry.fireObservedChange(this, "foo", getProperty("foo"));
	}
}

Comp.html:
Value of the foo parameter is: 
<span jwcid="@Insert" value="ognl:param.value"/>

Comp.jwc:
<component-specification class="helloworld.Comp" allow-body="yes"
allow-informal-parameters="yes">
	<parameter name="param" type="helloworld.Foo" direction="custom"/>    
</component-specification>

Comp.java:
public class Comp extends BaseComponent {
	public Foo getParam() {
		return (Foo) getBinding("param").getObject();
	}

	protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) {
		if (cycle.isRewinding()) {
			getParam().setValue(getParam().getValue() + 1);
		}
		super.renderComponent(writer, cycle);
	}
}

Foo.java:
public class Foo implements Serializable {
	int value;
	
	public Foo() {
		value = 0;
	}
	
	public int getValue() {
		return value;
	}
	public void setValue(int value) {
		this.value = value;
	}
}

--
Author of an e-Book for learning Tapestry (http://www.agileskills2.org/EWDT)


---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Binding confusion

Posted by Robert <rv...@xs4all.nl>.
Mind Bridge wrote:

>>However if I call a setter on the parameter this change has
>>dissapeared the next time I call getBinding().getObject().
>>    
>>
>
>Please call getBinding().setObject() after you make the change.
>

I get an ognl.NoSuchPropertyException if I do that.



---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Binding confusion

Posted by Mind Bridge <mi...@yahoo.com>.
Hi,

> Anyway the confusion is that each time I call getBinding().getObject()
> I noticed that I get an object with a different address.

I am not sure why that would happen on a single machine (do you use OGNL?),
but in a cluster that would obviously be true -- the objects will be
different on different machines, as they have to go through serialization
and deserialization. In general (this does not refer only to Tapestry, but
to pretty much everything) using == rather than .equals() is a bad idea.

> However if I call a setter on the parameter this change has
> dissapeared the next time I call getBinding().getObject().

Please call getBinding().setObject() after you make the change. This may be
related to the issue mentioned above. Tapestry needs to be notified that
something has changed. If it is not, it will not update the object in the
session and your changes would be lost. If the object was the same, you may
go by without that notification, as the object would be changed anyway. But
the prudent thing is to _always_ notify Tapestry that a modification has
occurred. That guarantees that your code will work on a variety of App
Servers, and in a cluster. Again, this is not so much a Tapestry-specific
issue.

Hope this helps,
-mb

----- Original Message ----- 
From: "Robert" <rv...@xs4all.nl>
To: "Tapestry users" <ta...@jakarta.apache.org>
Sent: Tuesday, July 05, 2005 10:36 AM
Subject: Re: Binding confusion


> Robert wrote:
>
> > Hi!
> > I am having some questions regarding to bindings.
> >
>
> It seems my questions are not answered on both the mailing list and
> forum which makes me worry about continuing to use tapestry.
> I am curious why not. Is it because
> 1) The question is too difficult
> 2) This has been asked many times before and people are bored to answer
> it again
> 3) My question is not formulated correctly and therefore incomprehensible
> 4) Something else
>
>
> > I have a component with one parameter which is a complex object that
> > includes some setters. I have set the direction to custom. I have done
> > it because I need to access it before the render phase. And also
> > because I can implement the methods to access the parameter myself and
> > avoid to use abstract classes (bad design in my opinion).
> >
> > Anyway the confusion is that each time I call getBinding().getObject()
> > I noticed that I get an object with a different address. They do have
> > the correct values set by the page that created this parameter.
> > However if I call a setter on the parameter this change has
> > dissapeared the next time I call getBinding().getObject().
> >
> > I have avoided this problem by using an instance field with the
> > parameter type and set it the first the the parameter is accessed.
> > This works fine for the pre-render and render phase.
> >
> > The problem I am having now is with the combination of cleaning up the
> > parameter and making changes available in an action (long after the
> > render has finished).
> >
> > Maybe a little bit of pseudo-code will make things more clear want I
> > would like...
> >
> > *Code:*
> >
> > private MyObject param;
> > private MyObject getParam()
> > {
> >    if (param == null)
> >        param = getBinding().getObject();
> >    return param;
> > }
> >
> > protected renderComponent()
> > {
> >    getParam().setValue(1);
> >    ....
> > }
> >
> > public action()
> > {
> >    int x = getParam().getValue();
> > }
> >
> >
> >
> > My questions are:
> > 1) Is it possible to keep the update in the object without having an
> > instance variable?
> > 2) How and when can I cleanup the instance variable (set it to null)?
> > If I do it in cleanupAfterRender it means that the update is not
> > available in the action handler.
> > 3) Will the component object that is used for the action not always
> > the same object used to render? And therefore instance variables
> > should not be trusted between those phases?
> >
> > Any background information related to these topics is very welcome to
> > increase my knowledge about Tapestry.
> >
> > TIA!
> > Robert.
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Binding confusion

Posted by Robert <rv...@xs4all.nl>.
Mikaël Cluseau wrote:

>I think this is mainly because if you try abstract classes you won't
>find it bad design at all ;-)
>
I did try it and found it quite annoying.
Maybe for small products it is not such a big problem...
Now my required parameters and types are checked at compile time and I 
love it. Who wouldn't want to catch errors at compile time?

Anyway it kinda is beside the point, because I had an optional parameter 
that had to be used before the rendering phase, so I was forced to use a 
custom binding anyway.
So even with abstract classes I still would have the same confusion.


---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Binding confusion

Posted by Mikaël Cluseau <nw...@nwrk.dyndns.org>.
I think this is mainly because if you try abstract classes you won't
find it bad design at all ;-) I think nobody does that here and, most
importantly, Tapestry 4.0 introduce even more abstract methods (for
getting services, pages, state objects, etc.) so abstract methods are
the way go.

Hope it helps...
Mikael.

Le mardi 05 juillet 2005 à 09:36 +0200, Robert a écrit :
> Robert wrote:
> 
> > Hi!
> > I am having some questions regarding to bindings.
> >
> 
> It seems my questions are not answered on both the mailing list and 
> forum which makes me worry about continuing to use tapestry.
> I am curious why not. Is it because
> 1) The question is too difficult
> 2) This has been asked many times before and people are bored to answer 
> it again
> 3) My question is not formulated correctly and therefore incomprehensible
> 4) Something else
> 
> 
> > I have a component with one parameter which is a complex object that 
> > includes some setters. I have set the direction to custom. I have done 
> > it because I need to access it before the render phase. And also 
> > because I can implement the methods to access the parameter myself and 
> > avoid to use abstract classes (bad design in my opinion).
> >
> > Anyway the confusion is that each time I call getBinding().getObject() 
> > I noticed that I get an object with a different address. They do have 
> > the correct values set by the page that created this parameter. 
> > However if I call a setter on the parameter this change has 
> > dissapeared the next time I call getBinding().getObject().
> >
> > I have avoided this problem by using an instance field with the 
> > parameter type and set it the first the the parameter is accessed. 
> > This works fine for the pre-render and render phase.
> >
> > The problem I am having now is with the combination of cleaning up the 
> > parameter and making changes available in an action (long after the 
> > render has finished).
> >
> > Maybe a little bit of pseudo-code will make things more clear want I 
> > would like...
> >
> > *Code:*
> >
> > private MyObject param;
> > private MyObject getParam()
> > {
> >    if (param == null)
> >        param = getBinding().getObject();
> >    return param;
> > }
> >
> > protected renderComponent()
> > {
> >    getParam().setValue(1);
> >    ....
> > }
> >
> > public action()
> > {
> >    int x = getParam().getValue();
> > }
> >
> >
> >
> > My questions are:
> > 1) Is it possible to keep the update in the object without having an 
> > instance variable?
> > 2) How and when can I cleanup the instance variable (set it to null)? 
> > If I do it in cleanupAfterRender it means that the update is not 
> > available in the action handler.
> > 3) Will the component object that is used for the action not always 
> > the same object used to render? And therefore instance variables 
> > should not be trusted between those phases?
> >
> > Any background information related to these topics is very welcome to 
> > increase my knowledge about Tapestry.
> >
> > TIA!
> > Robert.
> >
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Binding confusion

Posted by Robert <rv...@xs4all.nl>.
Robert wrote:

> Hi!
> I am having some questions regarding to bindings.
>

It seems my questions are not answered on both the mailing list and 
forum which makes me worry about continuing to use tapestry.
I am curious why not. Is it because
1) The question is too difficult
2) This has been asked many times before and people are bored to answer 
it again
3) My question is not formulated correctly and therefore incomprehensible
4) Something else


> I have a component with one parameter which is a complex object that 
> includes some setters. I have set the direction to custom. I have done 
> it because I need to access it before the render phase. And also 
> because I can implement the methods to access the parameter myself and 
> avoid to use abstract classes (bad design in my opinion).
>
> Anyway the confusion is that each time I call getBinding().getObject() 
> I noticed that I get an object with a different address. They do have 
> the correct values set by the page that created this parameter. 
> However if I call a setter on the parameter this change has 
> dissapeared the next time I call getBinding().getObject().
>
> I have avoided this problem by using an instance field with the 
> parameter type and set it the first the the parameter is accessed. 
> This works fine for the pre-render and render phase.
>
> The problem I am having now is with the combination of cleaning up the 
> parameter and making changes available in an action (long after the 
> render has finished).
>
> Maybe a little bit of pseudo-code will make things more clear want I 
> would like...
>
> *Code:*
>
> private MyObject param;
> private MyObject getParam()
> {
>    if (param == null)
>        param = getBinding().getObject();
>    return param;
> }
>
> protected renderComponent()
> {
>    getParam().setValue(1);
>    ....
> }
>
> public action()
> {
>    int x = getParam().getValue();
> }
>
>
>
> My questions are:
> 1) Is it possible to keep the update in the object without having an 
> instance variable?
> 2) How and when can I cleanup the instance variable (set it to null)? 
> If I do it in cleanupAfterRender it means that the update is not 
> available in the action handler.
> 3) Will the component object that is used for the action not always 
> the same object used to render? And therefore instance variables 
> should not be trusted between those phases?
>
> Any background information related to these topics is very welcome to 
> increase my knowledge about Tapestry.
>
> TIA!
> Robert.
>


---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org