#render: or #call: components.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

#render: or #call: components.

Edward Stow
Hi,

I have an application that has a body section, the body section can be
rendered with two or more components.  For example:

TemplateComponent
    - HeaderComponent
    - BodyComponent - one of BodyOne | BodyTwo | etc components.
    - FooterComponent


This question may be exposing my ignorance .... but I see two ways to
'paint' my page with components in response to user interaction with
my application.

1.  #render:  During the renderContentOn phase arrange for the
component (BodyOne | BodyTwo) to be #render:ed.

2.  #call: During the action phase arrange for the component (BodyOne
| BodyTwo) to be called from the current body component.  The #call:ed
component does not #answer.

What would be best practice?

Should #call: only be used for components that you expect to #answer
like a DatePicker, ColorChooser etc?

Thanks
--

Edward Stow
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: #render: or #call: components.

John Thornborrow
Hi,

#call: should only be used in a callback, or when using a WATask
subclass. (The latter leaves you no option anyway, as WATasks cannot/do
not render)

If you want multiple components rendered on the same page, you must use
#render:, if you want to pass control of the session to another
component, use #call: within a callback.

It is also worth noting the #onAnswer: message, this allows you to
render multiple components and ensure all will do specific action upon
answering. An example:

MyTask>>go
   self call: MyParentComponent new

MyParentComponent>>renderContentOn: html
   html render: (
     ChildComponentA new
       onAnswer: [ :val | self answer: val ];
       yourself).
   html render: (
     ChildComponentB new
       onAnswer: [ :val | self answer: val];
       yourself)


The block(s) sent to the child components will ensure that when they
#answer:, the parent component will #answer: the same value.

The above is useful when rendering a menu/navigation component, for example.

Hope this helps,

J.

Edward Stow wrote:

> Hi,
>
> I have an application that has a body section, the body section can be
> rendered with two or more components.  For example:
>
> TemplateComponent
>     - HeaderComponent
>     - BodyComponent - one of BodyOne | BodyTwo | etc components.
>     - FooterComponent
>
>
> This question may be exposing my ignorance .... but I see two ways to
> 'paint' my page with components in response to user interaction with
> my application.
>
> 1.  #render:  During the renderContentOn phase arrange for the
> component (BodyOne | BodyTwo) to be #render:ed.
>
> 2.  #call: During the action phase arrange for the component (BodyOne
> | BodyTwo) to be called from the current body component.  The #call:ed
> component does not #answer.
>
> What would be best practice?
>
> Should #call: only be used for components that you expect to #answer
> like a DatePicker, ColorChooser etc?
>
> Thanks

--
John Thornborrow
http://www.pinesoft.co.uk


******************************************************************************************************************************************
This email is from Pinesoft Limited. Its contents are confidential to the intended recipient(s) at the email address(es) to which it has been addressed. It may not be disclosed to or used by anyone other than the addressee(s), nor may it be copied in anyway. If received in error, please contact the sender, then delete it from your system. Although this email and attachments are believed to be free of virus, or any other defect which might affect any computer or IT system into which they are received and opened, it is the responsibility of the recipient to ensure that they are virus free and no responsibility is accepted by Pinesoft for any loss or damage arising in any way from receipt or use thereof. *******************************************************************************************************************************************


Pinesoft Limited are registered in England, Registered number: 2914825. Registered office: 266-268 High Street, Waltham Cross, Herts, EN8 7EA
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: #render: or #call: components.

Edward Stow
On Mon, Apr 28, 2008 at 8:07 PM, John Thornborrow <[hidden email]> wrote:
> Hi,
>
>  #call: should only be used in a callback, or when using a WATask subclass.
> (The latter leaves you no option anyway, as WATasks cannot/do not render)
>
>  If you want multiple components rendered on the same page, you must use
> #render:, if you want to pass control of the session to another component,
> use #call: within a callback.

I was aware of the limitations on using #render: and #call: - perhaps
my elaboration below will better illustrate my question.
>
>  It is also worth noting the #onAnswer: message, this allows you to render
> multiple components and ensure all will do specific action upon answering.

So .. adding the #onAnswer is the equivalent of using #call: in the
rendering process?

Elaboration:

1. Displaying sub components with #call:
-----------------------
ParentComponent>>renderContentOn: html

<render heading information >
html render: ChildComponentA new
<render footer informaton >

ChildComponentA>>renderContentOn: html

html anchor
    callback: [ self call: ChildComponentB new  ];
    with: 'Show child component B'

ChildComponentB>>renderContentOn: html

html anchor
    callback: [ self call: ChildComponentA new  ];
    with: 'Show child component A'

Or  2. Display with render: in sub components
---------------------------------------
ParentComponent>>renderContentOn: html

   html render: self bodyComponent.

#bodyComponent returns either a ChildComponentA or ChildComponentB instance.

ChildComponentA>>renderContentOn: html

html anchor
    callback: [ self showChildComponentB  ];
    with: 'Show child component B'

ChildComponentB>>renderContentOn: html

html anchor
    callback: [ self showChildComponentA  ];
    with: 'Show child component A'

The #showComponentX methods will indirectly communicate  with the
Parent via announcements, or perhaps via globally accessible object
like the session and set the bodyComponent in the parent ready for the
next rendering.

Both approaches result in the page rendered with the same content.
Are their any compelling reasons to use one over the other?

--

Edward Stow
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: #render: or #call: components.

Lukas Renggli
In reply to this post by John Thornborrow
>  MyParentComponent>>renderContentOn: html
>   html render: (
>     ChildComponentA new
>       onAnswer: [ :val | self answer: val ];
>       yourself).
>   html render: (
>     ChildComponentB new
>       onAnswer: [ :val | self answer: val];
>       yourself)

No component instantiation in the render method! Like this you get new
components every time you hit refresh or perform an action on the
page. This certainly does not work as expected.

You probably want something like this:

MyPageComponent>>initialize
    super initialize.
    childA := ChildComponentA new
       onAnswer: [ :val | self answer: val ];
       yourself.
    childB := ChildComponentB new
       onAnswer: [ :val | self answer: val ];
       yourself.

MyPageComponent>>children
    ^ Array with: childA with: childB

MyPageComponent>>renderContentOn: html
    html render: childA.
    html render: childB

Lukas

--
Lukas Renggli
http://www.lukas-renggli.ch
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: #render: or #call: components.

John Thornborrow
In reply to this post by Edward Stow
For that scenario, option 1 would be more suitable - simply because it
is much more simple and would be easier to maintain.

J.

Edward Stow wrote:

> On Mon, Apr 28, 2008 at 8:07 PM, John Thornborrow <[hidden email]> wrote:
>> Hi,
>>
>>  #call: should only be used in a callback, or when using a WATask subclass.
>> (The latter leaves you no option anyway, as WATasks cannot/do not render)
>>
>>  If you want multiple components rendered on the same page, you must use
>> #render:, if you want to pass control of the session to another component,
>> use #call: within a callback.
>
> I was aware of the limitations on using #render: and #call: - perhaps
> my elaboration below will better illustrate my question.
>>  It is also worth noting the #onAnswer: message, this allows you to render
>> multiple components and ensure all will do specific action upon answering.
>
> So .. adding the #onAnswer is the equivalent of using #call: in the
> rendering process?
>
> Elaboration:
>
> 1. Displaying sub components with #call:
> -----------------------
> ParentComponent>>renderContentOn: html
>
> <render heading information >
> html render: ChildComponentA new
> <render footer informaton >
>
> ChildComponentA>>renderContentOn: html
>
> html anchor
>     callback: [ self call: ChildComponentB new  ];
>     with: 'Show child component B'
>
> ChildComponentB>>renderContentOn: html
>
> html anchor
>     callback: [ self call: ChildComponentA new  ];
>     with: 'Show child component A'
>
> Or  2. Display with render: in sub components
> ---------------------------------------
> ParentComponent>>renderContentOn: html
>
>    html render: self bodyComponent.
>
> #bodyComponent returns either a ChildComponentA or ChildComponentB instance.
>
> ChildComponentA>>renderContentOn: html
>
> html anchor
>     callback: [ self showChildComponentB  ];
>     with: 'Show child component B'
>
> ChildComponentB>>renderContentOn: html
>
> html anchor
>     callback: [ self showChildComponentA  ];
>     with: 'Show child component A'
>
> The #showComponentX methods will indirectly communicate  with the
> Parent via announcements, or perhaps via globally accessible object
> like the session and set the bodyComponent in the parent ready for the
> next rendering.
>
> Both approaches result in the page rendered with the same content.
> Are their any compelling reasons to use one over the other?
>

--
John Thornborrow
http://www.pinesoft.co.uk


******************************************************************************************************************************************
This email is from Pinesoft Limited. Its contents are confidential to the intended recipient(s) at the email address(es) to which it has been addressed. It may not be disclosed to or used by anyone other than the addressee(s), nor may it be copied in anyway. If received in error, please contact the sender, then delete it from your system. Although this email and attachments are believed to be free of virus, or any other defect which might affect any computer or IT system into which they are received and opened, it is the responsibility of the recipient to ensure that they are virus free and no responsibility is accepted by Pinesoft for any loss or damage arising in any way from receipt or use thereof. *******************************************************************************************************************************************


Pinesoft Limited are registered in England, Registered number: 2914825. Registered office: 266-268 High Street, Waltham Cross, Herts, EN8 7EA
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: #render: or #call: components.

Edward Stow
On Mon, Apr 28, 2008 at 8:47 PM, John Thornborrow <[hidden email]> wrote:
> For that scenario, option 1 would be more suitable - simply because it is
> much more simple and would be easier to maintain.

Using the #call: - is much more direct and easier to maintain (for
this simple example) but are their undesirable side effects in using a
sequence of #call: s in a session that do not return?

--

Edward Stow
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: #render: or #call: components.

John Thornborrow
In reply to this post by Lukas Renggli
Yes, that was what I intended, my example was merely a demonstration of
#onAnswer:

John.

Lukas Renggli wrote:

>>  MyParentComponent>>renderContentOn: html
>>   html render: (
>>     ChildComponentA new
>>       onAnswer: [ :val | self answer: val ];
>>       yourself).
>>   html render: (
>>     ChildComponentB new
>>       onAnswer: [ :val | self answer: val];
>>       yourself)
>
> No component instantiation in the render method! Like this you get new
> components every time you hit refresh or perform an action on the
> page. This certainly does not work as expected.
>
> You probably want something like this:
>
> MyPageComponent>>initialize
>     super initialize.
>     childA := ChildComponentA new
>        onAnswer: [ :val | self answer: val ];
>        yourself.
>     childB := ChildComponentB new
>        onAnswer: [ :val | self answer: val ];
>        yourself.
>
> MyPageComponent>>children
>     ^ Array with: childA with: childB
>
> MyPageComponent>>renderContentOn: html
>     html render: childA.
>     html render: childB
>
> Lukas
>

--
John Thornborrow
http://www.pinesoft.co.uk


******************************************************************************************************************************************
This email is from Pinesoft Limited. Its contents are confidential to the intended recipient(s) at the email address(es) to which it has been addressed. It may not be disclosed to or used by anyone other than the addressee(s), nor may it be copied in anyway. If received in error, please contact the sender, then delete it from your system. Although this email and attachments are believed to be free of virus, or any other defect which might affect any computer or IT system into which they are received and opened, it is the responsibility of the recipient to ensure that they are virus free and no responsibility is accepted by Pinesoft for any loss or damage arising in any way from receipt or use thereof. *******************************************************************************************************************************************


Pinesoft Limited are registered in England, Registered number: 2914825. Registered office: 266-268 High Street, Waltham Cross, Herts, EN8 7EA
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: #render: or #call: components.

David Zmick
I know that this is probably a very bad practice, but I have initialized component, eg. a instance variable 'bodyComp'
 
ok, I will show some code:
 
RootComponent>>initilaize
   super initialize.
   self bodyComp: BodyComponent new.
 
RootComponent>>renderContentOn: html
   "all the head stuff"
    bodyComponent renderContentOn: html
    "etc."
 
I was wonderering how this was "correctley" done the other day, so I'm glad this thread popped up..  What is bad about my method, if anything, I just think it seems a little hackish...
ty


 
On Mon, Apr 28, 2008 at 9:27 AM, John Thornborrow <[hidden email]> wrote:
Yes, that was what I intended, my example was merely a demonstration of #onAnswer:

John.


Lukas Renggli wrote:
 MyParentComponent>>renderContentOn: html
 html render: (
   ChildComponentA new
     onAnswer: [ :val | self answer: val ];
     yourself).
 html render: (
   ChildComponentB new
     onAnswer: [ :val | self answer: val];
     yourself)

No component instantiation in the render method! Like this you get new
components every time you hit refresh or perform an action on the
page. This certainly does not work as expected.

You probably want something like this:

MyPageComponent>>initialize
   super initialize.
   childA := ChildComponentA new
      onAnswer: [ :val | self answer: val ];
      yourself.
   childB := ChildComponentB new
      onAnswer: [ :val | self answer: val ];
      yourself.

MyPageComponent>>children
   ^ Array with: childA with: childB

MyPageComponent>>renderContentOn: html
   html render: childA.
   html render: childB

Lukas


--
John Thornborrow
http://www.pinesoft.co.uk


******************************************************************************************************************************************
This email is from Pinesoft Limited. Its contents are confidential to the intended recipient(s) at the email address(es) to which it has been addressed. It may not be disclosed to or used by anyone other than the addressee(s), nor may it be copied in anyway. If received in error, please contact the sender, then delete it from your system. Although this email and attachments are believed to be free of virus, or any other defect which might affect any computer or IT system into which they are received and opened, it is the responsibility of the recipient to ensure that they are virus free and no responsibility is accepted by Pinesoft for any loss or damage arising in any way from receipt or use thereof. *******************************************************************************************************************************************


Pinesoft Limited are registered in England, Registered number: 2914825. Registered office: 266-268 High Street, Waltham Cross, Herts, EN8 7EA
_______________________________________________



--
David Zmick
/dz0004455\
http://dz0004455.googlepages.com
http://dz0004455.blogspot.com
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

RE: #render: or #call: components.

Ramon Leon-5
>
> I know that this is probably a very bad practice, but I have
> initialized component, eg. a instance variable 'bodyComp'
>  
> ok, I will show some code:
>  
> RootComponent>>initilaize
>    super initialize.
>    self bodyComp: BodyComponent new.
>  
> RootComponent>>renderContentOn: html
>    "all the head stuff"
>     bodyComponent renderContentOn: html
>     "etc."
>  

Don't do that, you should render subcomponents with #render:, never call
renderContentOn: of another component.

RootComponent>>renderContentOn: html
     html render: bodyComponent

Ramon Leon
http://onsmalltalk.com

_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: #render: or #call: components.

stephane ducasse
In reply to this post by David Zmick
then your children should return this new component.

stef
On Apr 29, 2008, at 2:43 AM, David Zmick wrote:

> I know that this is probably a very bad practice, but I have  
> initialized component, eg. a instance variable 'bodyComp'
>
> ok, I will show some code:
>
> RootComponent>>initilaize
>    super initialize.
>    self bodyComp: BodyComponent new.
>
> RootComponent>>renderContentOn: html
>    "all the head stuff"
>     bodyComponent renderContentOn: html
>     "etc."
>
> I was wonderering how this was "correctley" done the other day, so  
> I'm glad this thread popped up..  What is bad about my method, if  
> anything, I just think it seems a little hackish...
> ty
>
>
>
> On Mon, Apr 28, 2008 at 9:27 AM, John Thornborrow  
> <[hidden email]> wrote:
> Yes, that was what I intended, my example was merely a demonstration  
> of #onAnswer:
>
> John.
>
>
> Lukas Renggli wrote:
>  MyParentComponent>>renderContentOn: html
>  html render: (
>    ChildComponentA new
>      onAnswer: [ :val | self answer: val ];
>      yourself).
>  html render: (
>    ChildComponentB new
>      onAnswer: [ :val | self answer: val];
>      yourself)
>
> No component instantiation in the render method! Like this you get new
> components every time you hit refresh or perform an action on the
> page. This certainly does not work as expected.
>
> You probably want something like this:
>
> MyPageComponent>>initialize
>    super initialize.
>    childA := ChildComponentA new
>       onAnswer: [ :val | self answer: val ];
>       yourself.
>    childB := ChildComponentB new
>       onAnswer: [ :val | self answer: val ];
>       yourself.
>
> MyPageComponent>>children
>    ^ Array with: childA with: childB
>
> MyPageComponent>>renderContentOn: html
>    html render: childA.
>    html render: childB
>
> Lukas
>
>
> --
> John Thornborrow
> http://www.pinesoft.co.uk
>
>
> ******************************************************************************************************************************************
> This email is from Pinesoft Limited. Its contents are confidential  
> to the intended recipient(s) at the email address(es) to which it  
> has been addressed. It may not be disclosed to or used by anyone  
> other than the addressee(s), nor may it be copied in anyway. If  
> received in error, please contact the sender, then delete it from  
> your system. Although this email and attachments are believed to be  
> free of virus, or any other defect which might affect any computer  
> or IT system into which they are received and opened, it is the  
> responsibility of the recipient to ensure that they are virus free  
> and no responsibility is accepted by Pinesoft for any loss or damage  
> arising in any way from receipt or use thereof.  
> *******************************************************************************************************************************************
>
>
> Pinesoft Limited are registered in England, Registered number:  
> 2914825. Registered office: 266-268 High Street, Waltham Cross,  
> Herts, EN8 7EA
> _______________________________________________
> seaside mailing list
> [hidden email]
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
>
>
>
> --
> David Zmick
> /dz0004455\
> http://dz0004455.googlepages.com
> http://dz0004455.blogspot.com 
> _______________________________________________
> seaside mailing list
> [hidden email]
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside

_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: #render: or #call: components.

stephane ducasse
In reply to this post by Ramon Leon-5
Yes and follow what ramon is saying.
you should not call renderContentOn: on your own.

>>
>> I know that this is probably a very bad practice, but I have
>> initialized component, eg. a instance variable 'bodyComp'
>>
>> ok, I will show some code:
>>
>> RootComponent>>initilaize
>>   super initialize.
>>   self bodyComp: BodyComponent new.
>>
>> RootComponent>>renderContentOn: html
>>   "all the head stuff"
>>    bodyComponent renderContentOn: html
>>    "etc."
>>
>
> Don't do that, you should render subcomponents with #render:, never  
> call
> renderContentOn: of another component.
>
> RootComponent>>renderContentOn: html
>     html render: bodyComponent
>
> Ramon Leon
> http://onsmalltalk.com
>
> _______________________________________________
> seaside mailing list
> [hidden email]
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
>

_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: #render: or #call: components.

David Zmick
ok, thank you, and sorry for a delayed reply, my internet has been down

On Tue, Apr 29, 2008 at 12:04 AM, stephane ducasse <[hidden email]> wrote:
Yes and follow what ramon is saying.
you should not call renderContentOn: on your own.



I know that this is probably a very bad practice, but I have
initialized component, eg. a instance variable 'bodyComp'

ok, I will show some code:

RootComponent>>initilaize
 super initialize.
 self bodyComp: BodyComponent new.

RootComponent>>renderContentOn: html
 "all the head stuff"
  bodyComponent renderContentOn: html
  "etc."


Don't do that, you should render subcomponents with #render:, never call
renderContentOn: of another component.

RootComponent>>renderContentOn: html
   html render: bodyComponent

Ramon Leon
http://onsmalltalk.com

_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside


_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside



--
David Zmick
/dz0004455\
http://dz0004455.googlepages.com
http://dz0004455.blogspot.com
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside