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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
分散システム、なんですぐ死んでしまうん?耐障害性を高めたいあなたのためのレジリエンスパターン入門
mshibuya
7
6.2k
技術記事、 専門家としてのプログラマ、 言語化
mizchi
14
7.5k
Embedded SREと共に達成した会員管理システムのAWS移行 - SRE NEXT 2026 ランチスポンサーセッション
niftycorp
PRO
1
2.6k
Hatena Engineer Seminar #37「言語モデルの活用に関する研究」
slashnephy
0
520
Laravelで学ぶ Webアプリケーションチューニング入門/web_application_tuning_101
hanhan1978
4
570
yield再入門 #phpcon
o0h
PRO
0
400
霧の中の代数的エフェクト
funnyycat
1
390
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
380
フィードバックで育てるAI開発
kotaminato
1
120
SLOをサービス品質の共通言語にするために 取り組んできたこと
wakana0222
0
500
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
150
광주소프트웨어마이스터고등학교 DevFest 특강 - 바이브 코딩 시대에서 주니어 개발자로 살아남는 방법
utilforever
1
130
Featured
See All Featured
Odyssey Design
rkendrick25
PRO
2
730
SEO for Brand Visibility & Recognition
aleyda
0
4.6k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
390
Exploring anti-patterns in Rails
aemeredith
3
440
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.7k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
650
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.4k
WENDY [Excerpt]
tessaabrams
11
38k
Designing for Performance
lara
611
70k
The World Runs on Bad Software
bkeepers
PRO
72
12k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
530
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