generating callback from ajax

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

generating callback from ajax

mmimica
I know I'm not supposed to reuse the canvas provided by
"WAComponent>>renderContentOn: html", but I am resusing it to generate
callbacks in ajax responses.
Something like this:
MyComponent>>renderContentOn: html
canvas := html.
... rendering ...
... registering callback ...

MyComponent>>ajaxCallback
| url |
  url := canvas actionUrl copy
                addField: (canvas callbacks store: (JSAjaxCallback on: [...]));
                yourself.
    self requestContext respond: [ :ret |
                ret doNotCache;
                        contentType: (WAMimeType applicationJson
                                charset: self requestContext handler charSet).
                url asString jsonOn: ret stream].


It works. The question is: Is it bad?


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

Re: generating callback from ajax

Johan Brichau-2
How are you registering the callback that will that call the #ajaxCallback method?
I'm asking because I see no reason to have such a construction. If you are registering an ajax callback that is supposed to render something (html, script, json, …) Seaside provides you with an appropriate renderContext. In all kinds of callbacks, you can therefore access the callbacks dictionary without needing to 'reuse' an old canvas / rendercontext.

As far as I understand it, if you are reusing the canvas of one render loop inside another loop (action or render callback), the url that is generated in your ajaxCallback method will contain an 'old' continuation key.
It probably only works correctly because ajax callbacks operate inside the last continuation state and do not create a new continuation. As a result, the continuation key remains the same and the 'old' key is thus always the 'current' key. This will probably mean that you will not get strange state results.

On 17 Sep 2011, at 16:31, Milan Mimica wrote:

> I know I'm not supposed to reuse the canvas provided by
> "WAComponent>>renderContentOn: html", but I am resusing it to generate
> callbacks in ajax responses.
> Something like this:
> MyComponent>>renderContentOn: html
> canvas := html.
> ... rendering ...
> ... registering callback ...
>
> MyComponent>>ajaxCallback
> | url |
>  url := canvas actionUrl copy
> addField: (canvas callbacks store: (JSAjaxCallback on: [...]));
> yourself.
>    self requestContext respond: [ :ret |
> ret doNotCache;
> contentType: (WAMimeType applicationJson
> charset: self requestContext handler charSet).
> url asString jsonOn: ret stream].
>
>
> It works. The question is: Is it bad?
>
>
> --
> Milan Mimica
> http://sparklet.sf.net
> _______________________________________________
> 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: generating callback from ajax

Julian Fitzell-2
Yes, I think you'll run into problems if you use the back button, open
multiple tabs, or start backtracking state.

As Johan says, AJAX callbacks are a bit weird because they operate
within an existing continuation. Some the likely changes in Seaside
3.1 may be of interest to you as the will expose the continuations
more easily within the callbacks - you would thus be able to access
the callback store for the current continuation.

I've also added pluggable continuations, which might actually be more
helpful to you, but I actually can't quite tell what you're trying to
accomplish here.

Julian

On Sat, Sep 17, 2011 at 5:13 PM, Johan Brichau <[hidden email]> wrote:

> How are you registering the callback that will that call the #ajaxCallback method?
> I'm asking because I see no reason to have such a construction. If you are registering an ajax callback that is supposed to render something (html, script, json, …) Seaside provides you with an appropriate renderContext. In all kinds of callbacks, you can therefore access the callbacks dictionary without needing to 'reuse' an old canvas / rendercontext.
>
> As far as I understand it, if you are reusing the canvas of one render loop inside another loop (action or render callback), the url that is generated in your ajaxCallback method will contain an 'old' continuation key.
> It probably only works correctly because ajax callbacks operate inside the last continuation state and do not create a new continuation. As a result, the continuation key remains the same and the 'old' key is thus always the 'current' key. This will probably mean that you will not get strange state results.
>
> On 17 Sep 2011, at 16:31, Milan Mimica wrote:
>
>> I know I'm not supposed to reuse the canvas provided by
>> "WAComponent>>renderContentOn: html", but I am resusing it to generate
>> callbacks in ajax responses.
>> Something like this:
>> MyComponent>>renderContentOn: html
>> canvas := html.
>> ... rendering ...
>> ... registering callback ...
>>
>> MyComponent>>ajaxCallback
>> | url |
>>  url := canvas actionUrl copy
>>               addField: (canvas callbacks store: (JSAjaxCallback on: [...]));
>>               yourself.
>>    self requestContext respond: [ :ret |
>>               ret     doNotCache;
>>                       contentType: (WAMimeType applicationJson
>>                               charset: self requestContext handler charSet).
>>               url asString jsonOn: ret stream].
>>
>>
>> It works. The question is: Is it bad?
>>
>>
>> --
>> Milan Mimica
>> http://sparklet.sf.net
>> _______________________________________________
>> 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
>
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: generating callback from ajax

mmimica
In reply to this post by Johan Brichau-2
On 17 September 2011 18:13, Johan Brichau <[hidden email]> wrote:
> How are you registering the callback that will that call the #ajaxCallback method?
> I'm asking because I see no reason to have such a construction. If you are registering an ajax callback that is supposed to render something (html, script, json, …) Seaside provides you with an appropriate renderContext. In all kinds of callbacks, you can therefore access the callbacks dictionary without needing to 'reuse' an old canvas / rendercontext.

I'm registering like this:
rendererContext := html.
dataUrl := rendererContext actionUrl copy
                addField: (rendererContext callbacks
                                                        store: (JSAjaxCallback on: [ self ajaxCallback ]));
                yourself.

And then inside ajaxCallback I want to register another callback and
respond the url of it :)

Why am I doing this? Well, trying to make best of jqGrid.
I want a separate callback for each row, when edited. I am storing the
callback url with the row data, in a hidden column, so the client
knows where to report edits for each row.  jqGrid obtains rows using a
AJAX request. Hence I need to register a callback for each row
returned to jqGrid in that AJAX request.

I could register a callback for each row in advance, but there is a
lot of rows and jqGrid does pagination... so that's not the way to go.
Hm... maybe I could preregister a few dozen of callbacks when
rendering and then in the callback just assign them to rows... could
work, but it's ugly.



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

Re: generating callback from ajax

Johan Brichau-2
Milan,

I think there are more convenient ways to achieve this, but it indeed seems to be difficult to add a callback in a text/json callback. I have to withdraw my statement:
> In all kinds of callbacks, you can therefore access the callbacks dictionary without needing to 'reuse' an old canvas / rendercontext.
It seems that a text/json callback does not give you a render context. Either there is another way to get to the callbacks (I would have to look), or it seems there is a shortcoming here because you might want to register new callbacks (or generate action urls) inside text/json callbacks as well.

So I understand why you are reusing the canvas.

In any case, I think registering a callback when you have the renderContext available is more convenient when you use the jQuery wrappers.
For example, the following expression registers a callback and returns the url so you can pass it on to JQGrid.

dataUrl := (html jQuery ajax callback:[self ajaxCallback]) fullUrl

However, when you want to return json, the following is probably more appropriate:

dataUrl := (html jQuery getJson text:[:stream | ... ]) fullUrl

And, the real problem, as opposed to the #html: , #script:, and #load: callbacks, the #text: callback does not provide a renderContext.

imho, it might be easier to use a single callback and a different request parameter for each row. In that case, you even do not need to register callbacks.
Another option is to create a #text: callback that passes the rendercontext (similar to how #script: & #html: are implemented).

Let me think about this a bit more… it's an interesting problem.

Johan

On 17 Sep 2011, at 19:23, Milan Mimica wrote:

> On 17 September 2011 18:13, Johan Brichau <[hidden email]> wrote:
>> How are you registering the callback that will that call the #ajaxCallback method?
>> I'm asking because I see no reason to have such a construction. If you are registering an ajax callback that is supposed to render something (html, script, json, …) Seaside provides you with an appropriate renderContext. In all kinds of callbacks, you can therefore access the callbacks dictionary without needing to 'reuse' an old canvas / rendercontext.
>
> I'm registering like this:
> rendererContext := html.
> dataUrl := rendererContext actionUrl copy
> addField: (rendererContext callbacks
> store: (JSAjaxCallback on: [ self ajaxCallback ]));
> yourself.
>
> And then inside ajaxCallback I want to register another callback and
> respond the url of it :)
>
> Why am I doing this? Well, trying to make best of jqGrid.
> I want a separate callback for each row, when edited. I am storing the
> callback url with the row data, in a hidden column, so the client
> knows where to report edits for each row.  jqGrid obtains rows using a
> AJAX request. Hence I need to register a callback for each row
> returned to jqGrid in that AJAX request.
>
> I could register a callback for each row in advance, but there is a
> lot of rows and jqGrid does pagination... so that's not the way to go.
> Hm... maybe I could preregister a few dozen of callbacks when
> rendering and then in the callback just assign them to rows... could
> work, but it's ugly.
>
>
>
> --
> Milan Mimica
> http://sparklet.sf.net
> _______________________________________________
> 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: generating callback from ajax

mmimica
On 18 September 2011 16:04, Johan Brichau <[hidden email]> wrote:
> imho, it might be easier to use a single callback and a different request parameter for each row. In that case, you even do not need to register callbacks.

This would be the normal way of doing it :)
All jqGrid operations usually operate on a single callback, sending
the ID of the row in question. The problem is my domain objects don't
have IDs. I am storing them in a object database (magma) so I don't
need IDs. I don't want to introduce them just to make the presentation
layer happy.


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

Re: generating callback from ajax

mmimica
On 18 September 2011 18:13, Milan Mimica <[hidden email]> wrote:
> need IDs. I don't want to introduce them just to make the presentation
> layer happy.

Oh is there something in Smalltalk like an address I could dereference
an object to, and then later reliable and uniquely reference that same
object using that address? Like a pointer or something.


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

Re: generating callback from ajax

Bob Arning
Not intrinsically, but you likely have, or could easily create, something. If you started with a collection of objects that you wanted to render on a page, you could use each object's index in the list as its ID. When the callback returned that index, you would know exactly which object it referred to.

Cheers,
Bob

On 9/19/11 3:15 AM, Milan Mimica wrote:
On 18 September 2011 18:13, Milan Mimica [hidden email] wrote:
need IDs. I don't want to introduce them just to make the presentation
layer happy.
Oh is there something in Smalltalk like an address I could dereference
an object to, and then later reliable and uniquely reference that same
object using that address? Like a pointer or something.



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

Re: generating callback from ajax

Lukas Renggli
This is what #passenger: automates. It assigns arbitrary objects to DOM nodes and retrieves them back later on. Look for senders, there are many examples using it.

Lukas

On Monday, 19 September 2011, Bob Arning <[hidden email]> wrote:
> Not intrinsically, but you likely have, or could easily create, something. If you started with a collection of objects that you wanted to render on a page, you could use each object's index in the list as its ID. When the callback returned that index, you would know exactly which object it referred to.
>
> Cheers,
> Bob
>
> On 9/19/11 3:15 AM, Milan Mimica wrote:
>
> On 18 September 2011 18:13, Milan Mimica <[hidden email]> <[hidden email]> wrote:
>
> need IDs. I don't want to introduce them just to make the presentation
> layer happy.
>
> Oh is there something in Smalltalk like an address I could dereference
> an object to, and then later reliable and uniquely reference that same
> object using that address? Like a pointer or something.
>
>
>

--
Lukas Renggli
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: generating callback from ajax

mmimica
In reply to this post by Bob Arning
On 19 September 2011 12:59, Bob Arning <[hidden email]> wrote:
> If you started with a collection of objects that you wanted to render on a
> page, you could use each object's index in the list as its ID. When the
> callback returned that index, you would know exactly which object it
> referred to.

Did this. Works fine, looks good. I think I'll stick to this method. Thanks.


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