Hi,

(Brief aside: JSON is a data format, like XML, HTML, RTF, etc.  Once
deserialized, JSON data becomes a JavaScript object (sometimes called
a POJO -- Plain Old JavaScript Object -- to indicate that it has no
special methods and such).  Although you hear people talking about
"JSON objects," it's a bit sloppy, basically a shorthand way of saying
"an object I got by deserializing JSON data.")

You can't "send methods" with JSON, JSON doesn't have a syntax for
that.  You can do so with JavaScript object literal syntax (JSON is
basically a subset of object literal syntax), but it would probably be
inefficient.  Instead, you can define your objects and their
behaviors, and then have them accept data from a POJO (perhaps as a
parameter to a constructor), which data comes across the wire in JSON
format.

So for example, defining a Book class:
* * * *
var Book = Class.create((function(){

    function initialize(bookdata) {
        this.data = bookdata;
    }

    function getAuthor() {
        if (!this.data.author) {
            // ...go get the author information...
        }
        return this.data.author;
    }

    return {
        initialize: initialize,
        getAuthor: getAuthor
    };

})());
* * * *

Getting a Book instance:
* * * *
// (Assumes 'thebook' is defined somewhere in scope)
new Ajax.Request(someurl, {
    onSuccess: function(response) {
        thebook = new Book(response.responseJSON);
    }
});
* * * *

Using a book(this is *NOT* literally following on from the code above)
* * * *
alert(thebook.getAuthor());
* * * *

Don't worry too much about that syntax, but the idea is that the
constructor accepts book data and gives you a Book, which then has
methods and such.

> ...if you can pause the javascript thread and make the call synchronous
> to that particular javascript thread or not.  Would such a synchronous
> call cause the browser to hang?

Smart man. :-)  The answers are yes, and yes.  You *can* hold up the
JavaScript thread while waiting for your Ajax call to complete, but
doing so tends to lock up the UI of the browser pretty badly (some
browser won't even repaint what they're already displaying if the
window is uncovered).  It's seriously not recommended.

Instead, callbacks become your friend.  It requires a marked change to
one's thinking (at least it did to mine!), but you basically recast
your code in request-and-response style.  So we'd change our getAuthor
method:

* * * *
    function getAuthor(cb) {
        if (!this.data.author) {
            // Go get the author information
            new Ajax.Request(someurl, {
                parameters:  {'id': this.data.bookid, 'command':
'getauthor'},
                onSuccess: function(response) {
                    this.data.author = response.responseJSON;
                    cb(this.data.author);
                }
            });
        }
        else {
            cb.defer(this.data.author);
        }
    }
* * * *

And then using it:
* * * *
thebook.getAuthor(function(author) {
    alert(author);
});
* * * *

Here we've said that getAuthor doesn't return a value at all; instead,
it accepts a function to call with the answer.  If we don't already
have the author, we go get it with an asynchronous Ajax call, and then
call the callback with the result (after caching the result); if we
already have the data, we call the callback instead -- either
directly, or indirectly via Function#defer (which is what I've done
above), which will call it the next time the interpreter is idle
(e.g., after a very very short pause).  The advantage to using
Function#defer is that whether we already have the author data or not,
the callback isn't triggered until after the getAuthor call is
complete, which helps the user of the class avoid making mistakes like
assuming the callback will be called immediately.  But you could just
call `cb` directly instead.

The upshot of this is that you probably wouldn't want to do this
except for data where there's a big advantage in deferring retrieval.
So probably not a book's author, but perhaps a book's *contents*. :-)
Or some other data that requires complex server-side processing to
retrieve.

Obviously there's a lot more to be said on this subject, but that's
the gist of my experience of it.

Good luck!

HTH,
--
T.J. Crowder
Independent Software Consultant
tj / crowder software / com
www.crowdersoftware.com


On Oct 3, 7:31 pm, pedz <pedz...@gmail.com> wrote:
> In ActiveRecord, a "has many" method for a class is what they call a
> proxy object.  It sits there and does nothing until an access like
> book.authors[0].first_name causes a database search for authors of the
> book.  Once the query has completed, further uses do not cause a db
> query (generally).
>
> Has anyone done a similar concept for json objects?
>
> For example, if I send book over as a json object, also send a method
> called authors.  authors originally would be a method that would first
> do an ajax call with the proper url back to the server to populate the
> relation.  Subsequent uses would just use what has already been
> fetched.  Right now, I'm wanting just read capability and not update
> capability but it seems like update capability would be plausible as
> well.
>
> What I don't know (because I don't know enough how browsers work) is
> if you can pause the javascript thread and make the call synchronous
> to that particular javascript thread or not.  Would such a synchronous
> call cause the browser to hang?  And then there is the whole question
> of retries and failure modes.
>
> The other choice (which seems super hard) would be to kick off the
> ajax call and basically do a context switch.  When the call completed,
> find the context it is associated with and resume the path.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to