Dispatches From the Edge: Polymorphic Records

written by Tyler Keating

We have good news for anyone using the experimental polymorphism framework from within SproutCore. You’ll be glad to know that it has now made its way into the official datastore framework as part of SC.Record. If you have been using this framework, you’ll be even more glad to learn that polymorphic records are now significantly faster and more memory efficient. As well, this change includes a critical bug fix that resulted in polymorphic records getting mismatched when their id was changed.

For those interested in what this change means, here’s how it works. First, if you’re not familiar with polymorphism, it’s similar to inheritance, but differs in that polymorphic subclasses share a common “identity”. Here’s what that means with respect to the data model. In typical inheritance, the subclasses inherit the traits (attributes) of their superclass, but they can’t stand-in for that superclass (i.e. their identity or type is unique). In polymorphic inheritance, the subclass still inherits the traits of the superclass, but is now also considered to be the “same” type as the superclass. This means that when you query for records of a polymorphic super type, you’ll also receive records of all the polymorphic sub types.

This is especially useful functionality, because data is often stored in exactly this type of generic manner. It’s typical in SQL databases to have a large table where certain attributes apply to one specific subtype of the data, other attributes apply to another subtype and some attributes apply to all. With polymorphism, we can model this situation precisely.

So how do we use it in SproutCore? It’s simply a matter of adding the isPolymorphic property to a record class and extending it. Let’s look at an example from the SC.Record documentation that will hopefully clear up any remaining confusion on how polymorphism works.

// This is the "root" polymorphic class. All subclasses of MyApp.Person 
// will be able to stand-in as a MyApp.Person.
 MyApp.Person = SC.Record.extend({
   isPolymorphic: true
 });
 
// As a polymorphic subclass, MyApp.Female is "equal" to a MyApp.Person.
 MyApp.Female = MyApp.Person.extend({
   isFemale: true
 });
 
// As a polymorphic subclass, MyApp.Male is "equal" to a MyApp.Person 
// also. Not it is not "equal" to a MyApp.Female.
 MyApp.Male = MyApp.Person.extend({
   isMale: true
 });
 
// Load two unique records into the store.
 MyApp.store.createRecord(MyApp.Female, { guid: '1' });
 MyApp.store.createRecord(MyApp.Male, { guid: '2' });
 
// Now we can see that these records are in fact "equal" to each other. 
// Which means that if we search for "people", we get "males" & 
// "females".
 var female = MyApp.store.find(MyApp.Person, '1'); // Returns record.
 var male = MyApp.store.find(MyApp.Person, '2'); // Returns record.
 
// These records are MyApp.Person as well as their unique subclass.
 SC.kindOf(female, MyApp.Female); // true
 SC.kindOf(male, MyApp.Male); // true

Enjoy!

SproutCore Book Available

written by Tyler Keating

Although it has been out for a couple weeks already, I had never officially announced the completion of the SproutCore Web Application Development book in this blog. So for anyone that has been waiting for a book on SproutCore, you should know that it has finally been completed and you can purchase a copy here.

This book covers almost every aspect of SproutCore with detailed explorations of the runtime environment, the MVC layers that SproutCore brings, using statecharts, interacting with multiple remote data stores and many many other topics all the way through to unit testing and deploying real SproutCore applications. So if you’re looking to take the next big leap in web software development and have ever been curious about SproutCore, now is your chance to learn everything you need to know in one easy read.

Thank you!

 

Dispatches From the Edge: Automatic Transitions and SC.View Optimizations

written by Tyler Keating

Version 1.10 is shaping up to be a fundamental advancement of SproutCore as the best framework for creating powerful user experiences on the web.  We’ve already been doing the best of breed practices for creating dynamic web applications for some time.  For example, running in the client, maintaining the application “truth” in code, minimizing touching the DOM and many other practices that keep SproutCore apps as fast as possible.  These features allow you to create extremely complex interfaces that update instantly as the user interacts with them.  However, while instant updates were a major advancement, they can give the interface a jarring feel and therefore the next level of application design is to go beyond instant updates and add “life” or “play” to your user interface with subtle transitions.

As such, SproutCore 1.10 will include a new automatic transition architecture that is so easy to use, developers can actually play around with complex transitions while first implementing a view rather than needing to commit more time to it later.  To do so, you simply specify a transition plugin to use during one of the four state changes: appending, becoming visible, becoming hidden and removing.  To make it even easier, SproutCore includes a few built-in transition plugins: SC.View.FADE, SC.View.MOVE, SC.View.BOUNCE, SC.View.SPRING and SC.View.SCALE and it’s very easy to write your own transition plugins to do any type of advanced animation based on the SC.Transition protocol.

Continue reading

SproutCore 1.9.2 Released

written by Tyler Keating

We are pleased to announce the immediate release of SproutCore 1.9.2.  This release contains important fixes to the 1.9 code-base and is fully backwards compatible.  We recommend that all users of SproutCore upgrade to this latest version in order to have the best development experience.  To upgrade to the latest version, simply run:

gem update sproutcore

This is a patch release and contains the following bug fixes:

Build Tools

  • We’ve softened the build tools dependency requirements from being ultra-pessimistic (i.e. within the minor version) to being just pessimistic (i.e. within the major version).  This helps to prevent Bundler conflicts.
  • Fixes the snake case generator for ‘sproutcore gen‘, so that names like ‘SCProject’ get properly transformed to ‘sc_project‘ and not ‘s_c_project‘.
  • Fixes the ‘$repeat: repeat‘ property used with the @slice SCSS directive when generating the @2x version.  It was incorrectly appending @2x to the end of the whole path (ex. /resources/images/image-sliced-from.png@2x) instead of inserting it before the extension (ex. /resources/images/image-sliced-from@2x.png).
  • Fixes incorrectly named “responder” generator to “state” generator for generating SC.State subclasses.  You can now generate an SC.State file using ‘sproutcore gen state‘ or ‘sc-gen state‘.
  • Added support for un-prefixed background-size CSS attribute when spriting.  This allows spriting to work properly in retina Firefox.
  • Fixes inconsistencies and improper syntax in several templates created with ‘sproutcore gen‘.  Generated files are now cleaner and provide more descriptive help comments.
  • Fixes missing stylesheet warnings on a clean app generated with ‘sproutcore gen app‘ or ‘sproutcore gen statechart_app‘ by adding a default stylesheet to the app. Also adds a default stylesheet to a design, when using ‘sproutcore gen design‘ (i.e. creating an SC.Page resource).

Framework

  • Fixes regression in IE7 and IE8 which caused XHR requests to fail to notify.
  • Fixes improper binary search used by SC.ManyArray.prototype.addInverseRecord that resulted in an infinite loop when using addInverseRecord with an orderBy function.
  • Fixes bug that allowed the context menu to appear regardless of overriding contextMenu in a view or setting SC.CONTEXT_MENU_ENABLED (globally) or isContextMenuEnabled (on a view) to false.  This makes the context menu event handling behave the same as the key, mouse, etc. event handling.
  • Fixes actions: insertNewLine, deleteForward, deleteBackward, moveLeft, moveRight, selectAll, moveUp and moveDown to be always handled by the SC.TextFieldView element when it has focus.
  • Fixes the hint value for SC.LabelView so that it will appear when the label has no value and isEditable is true.
  • No longer modifies the underlying items given to an SC.SegmentedView directly so that we don’t dirty the original objects.
  • Fixes debug files being included in builds. These files (one of which is a 2.5MB test image) would get included into every build, because they were at the wrong path.  These files should not ever be loaded in an app, but if you created an app manifest based on the contents of the built static directory, you could invariably cause the client to download over 2.5MB of files that are never used.
  • Fixes determination of touch support in Chrome on Win 8.
  • Adds missing un-prefixed border-radius rules to the default theme for browsers that have dropped the prefix.

As always, every bug fix includes an accompanying unit test to ensure that the bug does not re-appear in the future.

Dispatches From the Edge: Super Fast Collections

written by Tyler Keating

One of the most advanced changes coming in 1.10 is the formalization of a major enhancement to SproutCore’s collection views.  Some of you may have heard of, used or tried to use the SC.CollectionFastPath mixin which gives SproutCore’s collection views, namely SC.ListView and SC.GridView, a massive performance boost.  The performance boost comes from pooling the item view objects, pooling item view layers (i.e. elements) and re-positioning layers using layout styles without modifying the DOM tree.  By re-using objects and elements, we can increase the speed that our collections can update, making gigantic lists perform like butter, even on mobile.

However, using SC.CollectionFastPath was unwieldy and difficult to get working correctly.  Turning it on was not enough, you also had to provide a couple properties on your item view class that were totally undocumented.   Due to the fact that SC.CollectionView is already optimized to create item view objects and layers only for the visible portion of the collection, it could be hard to even be sure that the fast path code was active or not.  This is all changing in 1.10.

We believe that every SproutCore view should be as fast as possible out-of-the-box on every platform and so we’re making these improvements a part of SC.CollectionView directly.  This means that by default, SC.ListView and SC.GridView will be fully optimized without any further configuration.  That said, when creating custom item views, you should properly support render and update.  Since view performance is so important, you should already know how to do this and if you need a good example, check out the custom item views in the new demo in the SproutCore Showcase.  This demo was created to debug this new technology as well as to demonstrate working with gigantic lists.

For now, the feature is still being tested and fine-tuned and any additional real-world feedback is appreciated.  So please check it out on the SproutCore master branch and bring any issues forward so that they can be addressed before release.

Thanks!

 

For discussion, please use sproutcore@googlegroups.com or #sproutcore on IRC.

Note:  Whereas, before you needed to set properties to turn this on, you have to set properties to turn it off right now.  If for whatever reason, you don’t want to pool elements, you can set isLayerReusable to false on your custom item view and if you don’t want to pool views, you can set isReusable to false as well.

Dispatches From the Edge: Invoking “Next”

written by Tyler Keating

As the 1.10 release nears completion, I thought I’d better start writing about some of the many improvements now, lest the final release blog post would take me two days to write.  A lot of the changes, including today’s topic, were the result of working on big feature additions and discovering that more support was needed closer to the core.  Which brings me to the topic of this post:  SC.RunLoop.prototype.invokeNext. Continue reading

Wesley Workman & Tim Evans are now SproutCore Reviewers

written by Tyler Keating

Please join us in congratulating Tim and Wesley on achieving SproutCore Reviewer status.  They are two of the most active contributors and have shown that they share our ideal of making SproutCore the most feature rich and highest quality application development framework.

More importantly, please join us in thanking Tim and Wesley and all the Committers and Reviewers for the work they’ve done to get us here.  We ask a lot of our burgeoning team and we are fortunate to have such people.

Sprint Towards 1.8 Release

written by Tyler Keating

SproutCore is about to get a new release on February 29, 2012 and we want to kick it off with an important sprint over the last weekend of the month.  As an open-source project, the success of SproutCore depends on you and others like you, so please consider setting aside some time to get involved.  Thanks!

 

Aside:  We’ve decided that the next release of SproutCore will be titled 1.8.  It’s simply an indication that the code base has changed enough since the 1.7 beta, which should have been finalized some time ago but was missed during the rocky period when SproutCore 2.0 was determined no longer to present the future of SproutCore.

Welcome to Maurits Lamers and Mitch Oliver

written by Tyler Keating

Hot on the heels of last week’s introduction of five new team members, I’m pleased to announce that Maurits Lamers and Mitch Oliver have also signed on as SproutCore Committers. As with the people from my previous post, these names should be of no surprise to anyone who has been with SproutCore for some time.

For those that aren’t sure of the difference between Committers and Reviewers, Committers are actually required to work in their own branches in the repo and submit every change as a pull request to be accepted by a Reviewer. The Reviewers are allowed to make direct fixes, but will most likely submit anything at all substantial as a pull request too in order to get another Reviewer’s feedback and acceptance. Both roles also include the responsibility to try to move the outstanding issues and pull requests towards a resolution.

As you can tell from the above description, both roles are a lot of work and it takes people with a real dedication to the project to accept what can be a thankless and demanding task, so please take a moment to catch all of these people on #sproutcore and sproutcore@googlegroups.com and show them your support.