The Inevitability of the Desktop-class JavaScript Framework

Fred Brunel points out this quote from Joel Splosky late last year:

So if history repeats itself, we can expect some standardization of Ajax user interfaces to happen in the same way we got Microsoft Windows. Somebody is going to write a compelling SDK that you can use to make powerful Ajax applications with common user interface elements that work together. And whichever SDK wins the most developer mindshare will have the same kind of competitive stronghold as Microsoft had with their Windows API.

I remember reading Joel’s original post last year and agreeing very strongly with it.  I even drafted a nice long post but never had the time to polish it up.  I have no idea what SproutCore’s future will be, but I’m pretty convinced that a full cross-platform desktop-class JavaScript Framework is inevitable for the web, and Joel explains why better than I could.

30-second Tutorial on Models

To Create a New Model

In your terminal:


cd project-name
sc-gen model contacts/contact

This creates:

 

  • The model file in clients/contacts/models/contact.js
  • The unit test in clients/contacts/tests/models/contact.js
  • A fixtures file in clients/contacts/fixtures/contact.js

 

To Create Some Models

The attributes you get from the server should be simple JSON hashes.  They must have at least two properties:

 

  • type: A string identifying the model type.  By default, use the class name.  In this case “Contact”.
  • guid: A unique identifier.  This will be used to auto-merge/update records in the future.

Here is an example of some JSON data:


var records = [
  { type: "Contact", firstName: "Charles", lastName: "Jolley", guid: "contact-1", favoriteNumber: "3" }
];

 

All models are kept in an in-memory database called the Store.  To add records to the Store, you just get these data hashes from your server in whatever way you like and add them to the store like so:

SC.Store.updateRecords(records);

records should be an array of one or more data hashes.  Note that you can call this method as often as you need.  If you pass in data hashes with a type/guid matching an existing record, then the hash will simply update the record.  Otherwise, one new record instance will be found for each item.

If you want to try the following examples without having to create a new app, you can simply add some sample records to the fixtures file created in Step 1 above.  These fixtures will be auto-loaded into the Store on app load.

To Get Records

In your app, you can retrieve some records from the store using finder functions.  This call will find all the contacts in the store (this does not contact your server, it just uses whatever is in the local datastore.  You should load your records into the store first.):

var recs = Contacts.Contact.findAll();

To Edit Records

Just set and get properties on them.  If the properties are string type, you don’t even need to declare them:


var rec = Contacts.Contact.findAll()[0];
rec.set(’firstName’, ‘Joe’); // changes the firstName to Joe.

If you have a property that is not a string but some other type, you can add a line to the Contact class declaring the type:


Contacts.Contact = SC.Record.extend({
  favoriteNumberType: Number
});

Now when you get/set the favoriteNumber property, the Contact record will automatically convert it to/from a number.  This works for dates and can even work for other model objects, but that is for another tutorial.

To Save Records

You can get back out the attributes hash of a record by getting the attributes property:


var rec = Contacts.Contact.findAll().first();
var attrs = rec.get('attributes');

This will be a JSON-compliant hash that you can serialize and send back to your server in your favorite way.

Conclusion

That’s it for part 1.  There is a lot more you can do with the model layer.  As usual, the in-source docs are best and can be views on the doc viewer page.

 

Downtime

Well that was fun.  SproutCore made it on Digg today, which was cool.  But it brought down my cheap-o dreamhost shared server that I was using as a placeholder until we launched.  We are now up on the Sproutit-sponsored VDS we had planned from the beginning and everything should be available again.

Sorry for the offline!

WWDC Followup

The presentation for SproutCore went very well yesterday.  Thanks to everyone who attended.  The room was packed; I hear over 600 people showed up.  Here are some of my favorite quotes overheard afterwards:

  • “SproutCore is the sleeper hit of WWDC!”
  • “It’s like JavaScript on Rails”
  • “This is the most exciting thing I’ve seen in web development in a long time.”

I’m also really excited to see some of the cool apps I heard people talking about after the presentation!  Be sure to let us know on the mailing list when you have something cool to share.

Finally, a special thanks to Peter, who did a great job demoing SproutCore and Billy who helped answer questions.  Couldn’t have done it without you!

If you were at the conference and did any kind of write up on it, drop us a line or leave a comment we’ll link it up.

 

Moving to Git

I’ve been meaning to post this for awhile but I kept putting it off until I could put together more docs. Well, the docs still aren’t all done, but we’ve moved so here goes: SproutCore is moving to Git. Aside from the fact that all the cool kids are using Git these days, the primary reason for moving to Git is to make it easier for you developers to make your own copies of SproutCore and modify it yourself.

Trim methods; make changes; import SproutCore into your own project..and of course submit changes back to the root project. Git makes all of this much easier.

You can find information on how to get SproutCore from Git on the Hacking Page.

You can also find our new Ticketing System at Lighthouse.

New Feature: Property Chaining

I’ve just committed the latest changes to SproutCore to support property chaining.  This is an important change the SC API that could impact your code, though most likely only for the better.

The Old World

set() has always returned the value that you set of an object.  Since it was intended to replace the “=” in JS, this makes sense.  Just like you could do:

foo.bar = foo2.bar = c

You could do:

foo.set('bar', foo2.set('bar', c)) ;

The problem, of course, is that this model of setting values is not terribly useful.  In my informal survey, in fact, it appeared that almost no one actually uses it.

The New World

Enter the new world of chainable commands.  jQuery has gained a large following thanks mostly to its nifty chainability syntax.  Most methods return the object you just called a method on so you can chain commands like this:

$('.foo').show().css('color','red');

And all elements with CSS class ‘foo’ will be made visible and their color set to red.  Nice.  

This is a very useful way of writing JavaScript and we’re all about efficiency so SproutCore is moving towards a general pattern whereby methods that otherwise would return void, will now return this so you can do chaining.  The first place I’m implementing this pattern is in set().  With the latest SproutCore, instead of returning the value, set() now returns the receiver object.  Other property-related methods such as beginPropertyChanges() and endPropertyChanges() also do this.  This makes it easy to write compact code like this:


contact.beginPropertyChanges()
  .set('firstName','Charles')
  .set('lastName', 'Jolley')
  .endPropertyChanges();

Very compact!

What Do You Need To Change

Unless you’ve relied on the return value of set() in the past, you don’t need to do anything!  Just start enjoying the new compact syntax.  You don’t have to use it, but now it’s there for you.  If you have relied on the return value of set(), then you need to modify your code to use a separate get() on the method after you set it first.

The new SproutCore changes are available from git and SVN today and will be in the 1.0 release of the SproutCore gem.

 

A few mentions

I’ve been meaning to post these for a while, but SproutCore’s had a few good posts about it recently.

Here is an interview I did with InfoQ:

The most recent buzz on the web has been about Ajax and improved user experiences. Looking to the future, some suggest that the “old” client-server model will be the way to meet users expectations and demands. Could Client-Server computing be the follow-on to Web 2.0 technologies? - Client-Server Computing, the Future of the Web?

And a nice mention on TechCrunch:

MobileMe won’t be available until July, but you can at least get a feel for some of the service’s features by heading over to SproutCore and trying out their photo app. - Want to Try Out Apple’s MobileMe? Check Out SproutCore