session variable vs. dynamic variable

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

session variable vs. dynamic variable

Sophie424
I am using a session variable for my sub-component callbacks to gain access
to a root component (to trigger an ajax redraw). As Lukas had cautioned,
this couples my components to a session subclass and makes it harder to
reuse my components.

Two questions:

1. If WASession had an extensible dictionary of variables would it help?
What is the downside of doing that?

2. If I decide to use a WADynamicVariable instead, when should I bind it?
Within my root #renderContentOn? And will subcomponent callbacks see that
binding?

WADynamicVariable subclass: CurrentRoot ...

MyRoot>>renderContentOn: html
    CurrentRoot use: self during: [
        render self and children
    ]

SomeSubComponent>>callback
    CurrentRoot value ...

Thanks - Sophie



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

RE: session variable vs. dynamic variable

Ramon Leon-5
> I am using a session variable for my sub-component callbacks
> to gain access to a root component (to trigger an ajax
> redraw). As Lukas had cautioned, this couples my components
> to a session subclass and makes it harder to reuse my components.
>
> Two questions:
>
> 1. If WASession had an extensible dictionary of variables
> would it help?
> What is the downside of doing that?
>
> 2. If I decide to use a WADynamicVariable instead, when
> should I bind it?
> Within my root #renderContentOn? And will subcomponent
> callbacks see that binding?
>
> WADynamicVariable subclass: CurrentRoot ...
>
> MyRoot>>renderContentOn: html
>     CurrentRoot use: self during: [
>         render self and children
>     ]
>
> SomeSubComponent>>callback
>     CurrentRoot value ...
>
> Thanks - Sophie

Use announcements instead, break the coupling.

http://onsmalltalk.com/programming/smalltalk/maintaining-loose-coupling-in-s
easide-components/

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: session variable vs. dynamic variable

Sophie424

"Ramon Leon" <[hidden email]> wrote

> Use announcements instead, break the coupling.

I'd like to use announcements, but am not clear about two points:

I have a root component (R), and a n-level deep leaf component (L). A
callback on L needs to cause something like:
    html updater
      id: R id;
      callback: [:r |
        self doModelStuff.
        r render: R]
How would you recommend getting this effect with announcements?

Also, would requiring a custom session subclass to hold the announcer make
it hard to use my component elsewhere?

Thanks!

Sophie



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

RE: Re: session variable vs. dynamic variable

Ramon Leon-5

> "Ramon Leon" <[hidden email]> wrote
>
> > Use announcements instead, break the coupling.
>
> I'd like to use announcements, but am not clear about two points:
>
> I have a root component (R), and a n-level deep leaf
> component (L). A callback on L needs to cause something like:
>     html updater
>       id: R id;
>       callback: [:r |
>         self doModelStuff.
>         r render: R]
> How would you recommend getting this effect with announcements?
>
> Also, would requiring a custom session subclass to hold the
> announcer make it hard to use my component elsewhere?
>
> Thanks!
>
> Sophie

I wouldn't let a child component redraw anything on the parent or rerender
the parent.  Components should render themselves.  Off the top of my head,
I'd say if a child callback needs to refresh the parent, I'd have the
callback send an announcement with the rendering canvas as an argument, let
the parent catch the announcement and use that renderer to call any
necessary rendering methods.  The child need only be concerned with
announcing, which could be either a global session announcer, or its own
announcer that the parent registered interest in when it first created the
child.  Every object *can* be it's own announcer, this creates a simple
event system where any object can signal events.

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: session variable vs. dynamic variable

Vladimir Pogorelenko
In reply to this post by Sophie424

08.02.2008, в 7:58, itsme213 написал(а):

> I am using a session variable for my sub-component callbacks to gain  
> access
> to a root component (to trigger an ajax redraw). As Lukas had  
> cautioned,
> this couples my components to a session subclass and makes it harder  
> to
> reuse my components.

Your root component knows about children. And children knows about  
root. Why not just connect them explicitly on component side, like:

WARoot#initilize
        ...
        child := WAMyChild new; root: self.


WAMyChild#childMethod
        self doSomethingWith: self root.

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

Re: Re: session variable vs. dynamic variable

Holger Kleinsorgen-4
In reply to this post by Ramon Leon-5
Ramon Leon schrieb:

>> "Ramon Leon" <[hidden email]> wrote
>>
>>> Use announcements instead, break the coupling.
>> I'd like to use announcements, but am not clear about two points:
>>
>> I have a root component (R), and a n-level deep leaf
>> component (L). A callback on L needs to cause something like:
>>     html updater
>>       id: R id;
>>       callback: [:r |
>>         self doModelStuff.
>>         r render: R]
>> How would you recommend getting this effect with announcements?
>>
>> Also, would requiring a custom session subclass to hold the
>> announcer make it hard to use my component elsewhere?
 >

> I wouldn't let a child component redraw anything on the parent or rerender
> the parent.  Components should render themselves.  Off the top of my head,
> I'd say if a child callback needs to refresh the parent, I'd have the
> callback send an announcement with the rendering canvas as an argument, let
> the parent catch the announcement and use that renderer to call any
> necessary rendering methods.  The child need only be concerned with
> announcing, which could be either a global session announcer, or its own
> announcer that the parent registered interest in when it first created the
> child.  Every object *can* be it's own announcer, this creates a simple
> event system where any object can signal events.

This potentially reverses the problem: The root R now needs to know
about the leaf component L, which might be not desirable, because R does
not know L directly.

I had a similiar problem recently, and used the following approach,
which works quite well and decouples the components.

- add a back link from each child component to its parent (but keep it
private, no component should explicitely send stuff to its parent).

- implement #announceOrDelegate:. This method checks if there are any
subscribers for the specific announcement. If yes it is announced,
otherwise the component delegates the announcement to the parent
component (the only piece of code that uses the back link to the parent
component).

It's similiar to the upcast mechanism used by VisualWorks' views.


Also, I added a mechanism to reduce the amount of work and coupling
required by AJAX callbacks. Basically it works the following way:

- in the component that encloses the asynchronously updated area, the
render method looks like this:

renderContentOn: canvas
    ...
    canvas div
      id: canvas nextId;
      asyncRenderWith: [ : updateCanvas |
        self renderDynamicContentOn: updateCanvas
      ].


#asyncRenderWith: adds an AsyncAreaBrush to the canvas. AsyncAreaBrush
takes care of rendering the dynamic content immediately (using the given
canvas), and later rendering the updated area (in this example the
contents of the <div> element), using the canvas passed by the AJAX
framework (I'm currently using MooTools).

- in the component with the callback, the render method looks like this

renderContentOn: canvas
    ...
    canvas anchor
      asyncCallback: [ ... ];
      with: [ ...  ]

#asynCallback: traverses the brush parent hierarchy until it encounters
the AsyncAreaBrush, and let it create an updater for the callback.

This way, the component with the callback does not need to know any
details about the parent component. Also, it's easy to turn AJAX
requests off (by making #asyncRenderWith: simply evaluating the block,
and #asyncCallback: falling back to #callback:).
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Re: session variable vs. dynamic variable

Sophie424
"Holger Kleinsorgen" <[hidden email]> wrote

> - implement #announceOrDelegate:

Sounds promising, thanks.

> This way, the component with the callback does not need to know any
> details about the parent component. Also, it's easy to turn AJAX requests
> off (by making #asyncRenderWith: simply evaluating the block, and
> #asyncCallback: falling back to #callback:).

What block args & typical body goes into
    asyncCallback: [ ?? ]
Any rendering code at all? Or just model &/or component tree updates? Even
"id" is not required by the callback rendering method? Sounds quite nice.
Can you share a small example and/or the implementation?

Such things would be very useful in Seaside + SU.

- Sophie



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

Re: Re: Re: session variable vs. dynamic variable

Holger Kleinsorgen-4
itsme213 schrieb:

> "Holger Kleinsorgen" <[hidden email]> wrote
>
>> - implement #announceOrDelegate:
>
> Sounds promising, thanks.
>
>> This way, the component with the callback does not need to know any
>> details about the parent component. Also, it's easy to turn AJAX requests
>> off (by making #asyncRenderWith: simply evaluating the block, and
>> #asyncCallback: falling back to #callback:).
>
> What block args & typical body goes into
>     asyncCallback: [ ?? ]
> Any rendering code at all? Or just model &/or component tree updates? Even
> "id" is not required by the callback rendering method? Sounds quite nice.
> Can you share a small example and/or the implementation?
attached is a fileout of the required code (I hope I didn't miss
anything, it was part of a larger package).
it was implemented using VisualWorks 7.6 & seaside 2.8, so I don't know
if it can be filed in into other images (the "squeak" fileout was
created using VW's fileout compatibility code, I have never filed it
into a Squeak image). It uses Mootools, but should be easy to adapt to
other frameworks, by writing a specific subclass of AsyncUpdater.

the fileout includes a simple example component showing how to use both
features (see ExampleTreeComponent>>renderContentOn:, renderToggleOn:,
announceVisit)

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

SeasideEnhancements.zip (8K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Re: Re: session variable vs. dynamic variable

Holger Kleinsorgen-4
> attached is a fileout of the required code (I hope I didn't miss
> anything, it was part of a larger package)

Argh, I missed to remove the bogus method AsyncUpdatedArea>>with:.
It can & should be eliminated.
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Re: Re: session variable vs. dynamic variable

Vladimir Pogorelenko
In reply to this post by Holger Kleinsorgen-4
Hi, Holger!

I'm just trying your example.

09.02.2008, в 14:47, Holger Kleinsorgen написал(а):

>>
> attached is a fileout of the required code (I hope I didn't miss  
> anything, it was part of a larger package).
> it was implemented using VisualWorks 7.6 & seaside 2.8, so I don't  
> know if it can be filed in into other images (the "squeak" fileout  
> was created using VW's fileout compatibility code, I have never  
> filed it into a Squeak image). It uses Mootools, but should be easy  
> to adapt to other frameworks, by writing a specific subclass of  
> AsyncUpdater.
>
> the fileout includes a simple example component showing how to use  
> both features (see ExampleTreeComponent>>renderContentOn:,  
> renderToggleOn:, announceVisit)
>


and I got walkback when clicking on '+' with unknown method send  
#cull:cull:cull: could please look out where this method is located?

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

Re: Re: Re: session variable vs. dynamic variable

Holger Kleinsorgen-4
Vladimir Pogorelenko schrieb:
> and I got walkback when clicking on '+' with unknown method send
> #cull:cull:cull: could please look out where this method is located?

In VW 7.6 it's in the base image. For VW < 7.6 you can load the package
"BlockCulling" from the public repository
(http://www.cincomsmalltalk.com/CincomSmalltalkWiki/PostgreSQL+Access+Page).
I dont know if there is an equaivalent package for Squeak.

BlockClosure>>cull: anObject
        ^self numArgs = 0
                ifTrue: [self value]
                ifFalse: [self value: anObject]

BlockClosure>>cull: anObject cull: bObject
        ^self numArgs < 2
                ifTrue: [self cull: anObject]
                ifFalse: [self value: anObject value: bObject]


BlockClosure>>cull: anObject cull: bObject cull: cObject
        ^self numArgs < 3
                ifTrue: [self cull: anObject cull: bObject]
                ifFalse: [self value: anObject value: bObject value: cObject]
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Re: Re: session variable vs. dynamic variable

Sophie424
In reply to this post by Holger Kleinsorgen-4
"Holger Kleinsorgen" <[hidden email]> wrote

> attached is a fileout of the required code

Thanks!!

Any suggestion into these 2 loading problems (I hacked around both for now):

SubscriptionRegistry - does not exist in Squeak.

foo ifNotNil: [:arg | ...]
- Does VW allow block-with-arg to #ifNotNil? Squeak does not. If it just
passes in foo I can just patch this in.

Thanks - Sophie



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