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

classNameBindings: Dynamic CSS classes made easy

written by Dave Porter

As a mature framework, SproutCore is full of little features to make common tasks drop-dead simple – including some hidden gems. I recently added some documentation to the framework (and to the indispensable docs.sproutcore.com) for one of them, and wanted to highlight it here on the blog too.

Dynamically adding and removing CSS classes on a view is a common need — for example, to swap background images when a property changes. But there’s no obvious way to do this; I burned my share of time trying to crack it manually, and I’ve watched other devs do the same. The usual solution ends up being a custom renderer, but that’s messy and verbose, operates at the wrong level of abstraction, and opens the door to all kinds of bugs if you’re not intimately familiar with the render API.

Enter classNameBindings. It’s is a quirky but powerful little property that makes dynamic class names a breeze. (No relation to the convenience key format fooBinding, by the way.) Here’s what classNameBindings looks like:

Continue reading

When To Use SproutCore, and When Not To

written by Majd Taby

I could tell you to use SproutCore for every single web destination you build, but that would be disingenuous. SproutCore is built to address a certain class of applications that need the help of its robust binding and observer layer, as well as its ecosystem of packages (DataStore, gesture support, etc). There are other classes of applications that simply don’t have the same functionality.

On a spectrum of interactivity, you have Wikipedia on one end, and iCloud.com on the other. The high level of interactivity in a suite of applications like iCloud mandates a foundation that dictates architecture and allows the developers to think and develop at a higher level of abstraction. Wikipedia, on the other hand, lacks rich interactivity or client-side data management, so it does not need state management.

The key consideration you have to make is whether or not you need state management on the client (the browser). When I refer to “state” in this context, I’m referring to a couple of types of state:

  • Server data: If you need to fetch, store, and maintain a data set delivered to you from the server, then SproutCore’s bindings model and the DataStore package ensure that what the user sees and what your server knows about never get out of sync.
  • Application state: In an application’s UI, multiple related pieces of information are usually displayed simultaneously: the aggregate number of items in a list, a list of the most recent items in a collection, etc. Using traditional web development techniques to maintain this sort of application state necessitates a large amount of boilerplate code writing and upkeep.

Finally, SproutCore helps manage the complexity of the code base and keeps marginal-cost of new features low over the lifetime of your project.

The effort required to scale your application in terms of complexity grows at a much lower rate than a traditional, roll-your-own technique.

This is emergent from SproutCore’s binding and observer layer. Because you describe the path your data follows from the model layer to the view layer, any new feature that impacts the data in the model layer will automatically propagate through your application.

Alternatively, when using an event-driven system where you primarily respond to user action, adding a new feature requires you to review the list of current features in your application to ensure that the new addition integrates well with the others. This normally involves keeping disparate functionality in sync by hand, which can become unruly over time.

You, the application developer, write and maintain the application code. However, the community writes and maintains the framework code, allowing the benefits trickle down to you when you update the framework. As a result, by offloading the code you have to write from the application to the framework, you ensure that you build robust, interactive, and fast applications.

SC.UserDefaults: Easy preferences using client-side storage

written by SproutCore

One of the cool things about the release of FireFox 3.5 and IE8 is that all the major web browsers now support the HTML5 standard for client-side storage using localStorage.

SproutCore was designed from the beginning to yield apps that are offline-capable.  Given the widespread availability of this localStorage now, it’s time to start focusing offline mode to the framework.

About a year ago we added the SC.UserDefaults to provide easy client-side user preferences in SproutCore apps.  Now we just pushed live some fixes that make the code work on all modern browsers along with some new demo code to show you how it works.

Working with SC.UserDefaults is incredibly easy.  You just create an instance and then use get() and set() to read/write preference values; just like any other SproutCore object.  Setting properties will automatically save them to local storage.  The object is also bindings aware so you can easily bind to preferences from the other parts of your app.  In fact, this is how most of the demo application works.

In addition to simply reading/writing preferences to local storage, SC.UserDefaults also allows you to set a default appDomain and userDomain for these keys so that you can save preferences for different apps and users.  It also has a facility for you to load in a default set of preferences which will be returned if no override has been saved on the local browser.

MORE INFO

If you want to use SC.UserDefaults in your own app, there is a lot of info available for you now thanks to the hard work of so many team members.

Thanks to some recent additions to WebKit, method names in SproutCore apps now show up correctly

written by SproutCore

Thanks to some recent additions to WebKit, method names in SproutCore apps now show up correctly in the profiler and debugger!  Yay for better dev tools.  And props to Francisco for contributing these improvements to WebKit.

To see these improvements for yourself, just get the latest WebKit Nightly and SproutCore 1.0 code.  Then debug/profile to your heart’s content!

We did our final big postback yesterday for SC1.0.  This postback includes a brand new refactore

written by SproutCore

We did our final big postback yesterday for SC1.0.  This postback includes a brand new refactored set of Controllers and a CollectionView.  There’s a lot to dig into here, so let me start with one of my favorite features: Outlines.

Drawing an outline view is actually pretty tricky.  For the most part, you’re simply displaying a list of items with some items indented more than others.  SproutCore’s new CollectionView comes with support for inspecting a content array of items and rendering it as a tree, which is pretty cool.

Of course, usually your data structure for outlines is usually some kind of tree; not a flat list.  Keeping track of all the nodes in this tree to generate the list can be fairly difficult.

Until now at least.

The new SC.TreeController in SproutCore 1.0 accepts a root node for any tree-like data structure and automatically generates a flattened outline list suitable for display in a collection view.  It keeps track of changes to your data model and automatically updates this list as needed.

There are still a lot of bugs here – this is new code afterall – but I’ve put together a little demo app so you can see what I’m talking about.  It’s called “Outline” and its available on our demo site here:

Outline Demo »

We’re still chasing down a perf bug in Firefox for this so I suggest checking it out in a Webkit browser for now.    We’ll be publishing the code shortly.

Just another example of how SproutCore 1.0 can handle large amounts of data in the cloud with ease. (and without pagination!)

Introducing SC.Freezable and SC.Copyable

written by SproutCore

Link: Introducing SC.Freezable and SC.Copyable

Following up on my earlier post about adopting ES5 conventions.  One of the API changes we recently made to SproutCore 1.0 was the introduction of the SC.Freezable and SC.Copyable mixins (linked to this post).

SC.Freezable adds a freeze() method to objects that use it.  In ES5 engines, this will actually freeze the object so that further modifications raise an exception.  Today, it simply sets the isFrozen property to YES.  Mutating methods can then be implemented to throw an exception if they are called while the object isFrozen.

Freezing is most useful in conjunction with the SC.Copyable mixin.  This mixin defines some standard methods for copying an object.  copy() returns a clone of the object.  frozenCopy() returns a clone of the object that has been frozen.  If you call frozenCopy() of an object that is already frozen, the method simply returns itself.

This pattern is great because now if you want to modify an object, you can get a copy by calling copy().  Even if the object is frozen, you’ll get a new object that is not frozen.  Likewise, if you want to keep a copy of the object around for later use and you want to be sure it won’t change, you can use frozenCopy().  If the object you are working on is already frozen, this won’t allocate more memory and slow your program down, so its really efficient.

One of the big reasons ES5 introduces the concept of freezing is to make it easier to work with objects as a kind of primitive type.  For example, a Range – with an start and a length value – should often be treated like a primitive value like a number; once it is created it can never be changed.  Freezing makes this possible.

By using SC.Freezable, copy(), frozenCopy() you can take advantage of this new capability in ES5 in your SproutCore applications today simply by following this simple protocol.