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
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
320
yield再入門 #phpcon
o0h
PRO
0
430
アルゴリズムは何を圧縮しているのか ─ Haskell から育った「圧縮代数」というメンタルモデル
naoya
16
3.5k
共通化で考えるべきは、実装より公開する型だった
codeegg
0
240
OSINT for SRE: 学術論文とポストモーテムから探る システム障害の共通パターン / SRE NEXT 2026
tomoyk
1
3.8k
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
330
광주소프트웨어마이스터고등학교 DevFest 특강 - 바이브 코딩 시대에서 주니어 개발자로 살아남는 방법
utilforever
1
130
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
450
Foundation Models frameworkで画像分析
ryodeveloper
1
120
Honoでのサプライチェーン侵害対策 〜 3つのライブラリに学ぶ
yusukebe
7
1.9k
act1-costs.pdf
sumedhbala
0
230
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.2k
Ethics towards AI in product and experience design
skipperchong
2
330
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
150
Writing Fast Ruby
sferik
630
63k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
420
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
220
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
360
Code Reviewing Like a Champion
maltzj
528
40k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
190
Test your architecture with Archunit
thirion
1
2.3k
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