Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
A Guided Tour Through the SproutCore Jungle
Search
Florian Kugler
May 10, 2012
Programming
1.2k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
A Guided Tour Through the SproutCore Jungle
Florian Kugler
May 10, 2012
More Decks by Florian Kugler
See All by Florian Kugler
Pragmatic Core Data
floriankugler
0
8.2k
AppKit for UIKit developers
floriankugler
0
320
Interactive Animations
floriankugler
1
240
Parallele Programmierung (German!)
floriankugler
0
850
Graphics Performance across iOS Devices
floriankugler
5
1.2k
Other Decks in Programming
See All in Programming
RTSPクライアントを自作してみた話
simotin13
0
630
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
300
Javaの型とAI時代に型が大事な理由 / java types and type in AI era
kishida
2
150
A2UI という光を覗いてみる
satohjohn
1
150
ローカルLLMでどこまでコードが書けるか -拡張版 / How much code can be written on a local LLM Extended
kishida
12
4.4k
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
730
Webフレームワークの ベンチマークについて
yusukebe
0
180
技術的負債解消で開発者の未来を開く- AIの力でコード刷新
kmd2kmd
0
110
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
560
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.8k
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
150
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
260
Featured
See All Featured
Skip the Path - Find Your Career Trail
mkilby
1
150
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.3k
Ethics towards AI in product and experience design
skipperchong
2
310
The Limits of Empathy - UXLibs8
cassininazir
1
370
Technical Leadership for Architectural Decision Making
baasie
3
420
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2k
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
260
Odyssey Design
rkendrick25
PRO
2
700
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.9k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
230
Transcript
A Guided Tour Through the Jungle @floriankugler berlinjs.org/apps May 10th,
2012
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
What’s comparable? Cappuccino Sencha ExtJS Ember.js
A SproutCore History * 2007 Charles Jolley 2008 2009
1.0 Release 2010 1.4 Release 2010 Strobe Corp. 2010 + @wycats 2011 1.5 Release ...
A SproutCore History 1.5 Release 1.6 Release 2.0 beta Strobe
Corp.
A SproutCore History 1.5 Release 1.6 Release 2.0 beta amber.js
ember.js 1.8 Release ( 1.7 )
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
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
MVC Architecture DataStore Controllers Object | Array | Tree Views
Panes | Collections | Label | Button | CheckBox | ... Statechart
MVC Architecture Model App Controller View
The “V” Property Model Controller View Runloop mouseDown mouseUp keyDown
mouseMoved 1 2 3 4 5 KVO Bindings Call Call
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.[]’)
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’ }) ...
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’ }) ...
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’)); } });
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’)); } });
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); } });
Statecharts showContactsState editContactState editContactDefaultState editContactDeleteState editContact submit deleteContact confirm cancel
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’); } })
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’); } }) })
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
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
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!
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
Questions? @floriankugler mail@floriankugler.de