Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A Guided Tour Through the SproutCore Jungle

A Guided Tour Through the SproutCore Jungle

Florian Kugler

May 10, 2012
Tweet

More Decks by Florian Kugler

Other Decks in Programming

Transcript

  1. What is SproutCore? Cocoa inspired web application framework Large-scale, Desktop-grade

    applications Strict MVC (+ statechart) architecture Well defined application structure Backend agnostic Ruby build tools
  2. A SproutCore History * 2007 Charles Jolley  2008 2009

    1.0 Release 2010 1.4 Release 2010 Strobe Corp. 2010 + @wycats 2011 1.5 Release ...
  3. Status Quo SproutCore 1.4 SproutCore 1.8 ember.js SproutCore “core” (Modularization)

    Core SproutCore concepts Clear mission statement (Auto updating template views) Lightweight Fast, complex, large-scale apps Render delegates Auto updating template views Window-based apps Improved build tools Page-based apps Desktop browsers No build tools required
  4. Core Concepts Strict MVC architecture with well defined event/data flow

    KVC / KVO / Bindings Computed properties Build views with HTML & CSS, update with jQuery Statecharts
  5. MVC Architecture DataStore Controllers Object | Array | Tree Views

    Panes | Collections | Label | Button | CheckBox | ... Statechart
  6. KVC / KVO myObject.set(‘foo’, ‘bar’); fooDidChange: function() { console.log(‘foo changed

    to ‘ + this.get(‘foo’)); }.observes(‘foo’) enumerable = myObject.get(‘anArray’); enumerable.pushObject(‘foo’); anArrayDidChange: function() { console.log(‘anArray length: ‘ + this.getPath(‘anArray.length’); }.observes(‘*anArray.[]’)
  7. Bindings contactsController = SC.ArrayController.create(); contactController = SC.ObjectController.create({ contentBinding: ‘App.contactsController.selection’ });

    addressesController = SC.ArrayController.create({ contentBinding: ‘App.contactController.addresses’ }); addressController = SC.ObjectController.create({ contentBinding: ‘App.addressesController.selection’ }); ... street: SC.LabelView.design({ valueBinding: ‘App.addressController.streetName’ }) ...
  8. Computed Properties addressController = SC.ObjectController.create({ contentBinding: ‘App.addressesController.selection‘ fullName: function() {

    return this.get(‘firstname’) + ‘ ‘ + this.get(‘lastName’); }.property(‘firstName’, ‘lastName’).cacheable() }); ... name: SC.LabelView.design({ valueBinding: ‘App.addressController.fullName’ }) ...
  9. Custom Views App.AddressView = SC.View.extend({ displayProperties: [ ‘content’ ], render:

    function(ctx) { ctx.push( ‘<div class=”last-name”>‘ + this.getPath(‘content.lastName’) + ‘</div>’ ); }, update: function($) { $.find(‘last-name’).text(this.getPath(‘content.lastName’)); } });
  10. Custom Views App.AddressView = SC.View.extend(SC.ContentDisplay, { contentDisplayProperties: [ ‘lastName‘ ],

    render: function(ctx) { ctx.push( ‘<div class=”last-name”>‘ + this.getPath(‘content.lastName’) + ‘</div>’ ); }, update: function($) { $.find(‘last-name’).text(this.getPath(‘content.lastName’)); } });
  11. Custom Views App.AddressView = SC.View.extend(SC.ContentDisplay, { contentDisplayProperties: [ ‘lastName‘ ],

    displayProperties: [ ‘highlighted‘ ], ... update: function($) { $.find(‘last-name’).text(this.getPath(‘content.lastName’)); if (this.get(‘highlighted’)) { $.addClass(‘highlighted’); } else { $.removeClass(‘highlighted’); } }, mouseDown: function(evt) { this.set(‘highlighted’, YES); } });
  12. Statecharts editButton: SC.ButtonView.design({ ... action: ‘editContact’ }) showContactsState: SC.State.design({ editContact:

    function() { this.gotoState(‘editContactState’); } }) editContactState: SC.State.design({ enterState: function() { // setup view tree }, exitState: function() { // tear down view tree }, submit: function() { this.gotoState(‘showContactsState’); } })
  13. editContactState: SC.State.design({ initialSubstate: ‘editContactDefaultState’, enterState: function() { /* setup view

    tree */ }, exitState: function() { /* tear down view tree */ }, editContactDefaultState: SC.State.design({ submit: function() { ... }, deleteContact: function({ this.gotoState(‘editContactDeleteState’); }) }), editContactDeleteState: SC.State.design({ enterState: function() { /* setup view tree */ }, exitState: function() { /* tear down view tree */ }, confirm: function() { this.gotoState(‘showContactsState’); }, cancel: function() { this.gotoState(‘editContactDefaultState’); } }) })
  14. The Future The community is recovering from the disruptive changes

    during the last year SproutCore is actively maintained Roadmap discussions are ongoing... Interesting spin-off: Blossom (#blossom) Built off SproutCore 1.4 Canvas based view layer
  15. SproutCore and Mobile I wouldn’t recommend it Try it: touch.ebay.com

    It’s a lot of JavaScript to be downloaded and parsed (~ 600-800 kB) Too DOM heavy Keep an eye on Blossom, Ember.js
  16. For Whom is SproutCore? Complex, desktop-grade application? Rich user interaction?

    Handles a lot of data? Targets desktop browsers? ... Then SproutCore is a very well designed and mature application framework, check it out!
  17. Resources sproutcore.com Guides & API docs Install SproutCore as Ruby

    Gem Highly recommended to clone SC repo into the frameworks folder of your app #sproutcore frozencanuck.wordpress.com