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
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
【SRE NEXT 2026 Lunch Session】一人目専任SREの立ち上げを加速する ― AIと進めたオンボーディングで2分を0.04秒にした話
pkshadeck
PRO
0
3.6k
『コードを書く以外の』エンジニアリング〜課金基盤移行プロジェクト推進のためのTips4選
yuriko1211
0
590
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
210
TSX の <Hoge<Fuga>> という構文に驚いた話 / tsx-type-argument-syntax
kanaru0928
0
210
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
670
源内ハンズオン概要編
hideg
0
140
AI時代に設計が 最大の生産性レバーになる 意図駆動開発とデータを消さない設計|Don't Delete Your Data or Your Intent — Design as the Deepest Lever in the AI Era
tomohisa
1
740
Foundation Models frameworkで画像分析
ryodeveloper
1
600
仕様駆動開発の消費期限
watany
17
7.3k
torikago - Ruby::Boxで照らすモジュラモノリスの実行境界
se4weed
1
350
今さら聞けない .NET CLI
htkym
0
180
人間の目はかわらない、だからJPEGは30年もつ
yuzneri
12
18k
Featured
See All Featured
The Cost Of JavaScript in 2023
addyosmani
55
10k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Marketing to machines
jonoalderson
1
5.7k
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.3k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
2.3k
WCS-LA-2024
lcolladotor
0
790
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
360
The World Runs on Bad Software
bkeepers
PRO
72
12k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Documentation Writing (for coders)
carmenintech
77
5.4k
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