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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
Free forum by Nabble | Edit this page |