Download - SproutCore: Amber
SproutCore
Why?
building large apps in jQuery
?
?
View (DOM Manipulation)
Model (.data)
Controller (.bind)
View (DOM Manipulation)
jQuery
jQuery
jQuery
Following 187
Following 188
$(".follow-me").live("click", function() { var link = $(this).parent().prev(); var count = parseInt($("#following span.count").text());
var newLink = $("<li class='user'>") .append(link.clone());
$("#following").prepend(newLink); $("#following span.count").text(count + 1);});
D E F G
Following 187
Who to follow
Awycats · FollowYehuda Katz
Bokito · FollowCharles Jolley
Cwifelette · FollowLeah Silber
D E F G
Following 187
Who to follow
Awycats · FollowYehuda Katz
Bokito · FollowCharles Jolley
Cwifelette · FollowLeah Silber
Edge casesStart with less than 4
D E F
Following 187
Who to follow
Awycats · FollowYehuda Katz
Bokito · FollowCharles Jolley
Cwifelette · FollowLeah Silber
Edge casesStart with less than 4Unfollowing
A D E F
Following 188
Who to follow
Awycats · UnfollowYehuda Katz
Bokito · FollowCharles Jolley
Cwifelette · FollowLeah Silber
What's wrong?
Views need to know about each other
There are lots of views
There are lots of views
More complex apps==
more spaghetti
What's the right way?
Model objects
User
guidusernamegravatarisFollowed
self-contained
views
D E F G
Following 187
following.length
following[N]
[1][0] [2] [3]
Who to follow
Awycats · FollowYehuda Katz
Bokito · FollowCharles Jolley
Cwifelette · FollowLeah Silber
A.isFollowed
B.isFollowed
C.isFollowed
users
[0]
[1]
[2]
D E F G
Following 187
following
Who to follow
Awycats · FollowYehuda Katz
Bokito · FollowCharles Jolley
Cwifelette · FollowLeah Silber
recommendations
wired together by
the page
Twitter.following
User
isFollowedChanged: function() { var followed = this.get('isFollowed');
if(followed) { Twitter.following.unshiftObject(this); } else { Twitter.following.removeObject(this); }}.observes('isFollowed')
D E F G
Following 187
following
Users
Who to follow
Awycats · FollowYehuda Katz
Bokito · FollowCharles Jolley
Cwifelette · FollowLeah Silber
recommendations
Twitter.recommendations
Users
Who to follow
Awycats · FollowYehuda Katz
Bokito · FollowCharles Jolley
Cwifelette · FollowLeah Silber
recommendations
Twitter.recommendations
Users
click =>user.set('isFollowed', true)
What's Happening
Here?
D E F G
Following 187
following
Who to follow
Awycats · FollowYehuda Katz
Bokito · FollowCharles Jolley
Cwifelette · FollowLeah Silber
recommendations
TotallyIsolatedViews
TotallyIsolatedModels
User
guidusernamegravatarisFollowed
isFollowedChanged
Glued Together By the App
SC.MainPage.append({ pickFollowers: Twitter.PickFollowers.design({ recommendationsBinding: "Twitter.recommendations" }), listFollowers: Twitter.FollowerList.design({ followingBinding: "Twitter.following" })});
Views?
SC.TemplateView
Twitter.FollowersList = SC.TemplateView.extend({ // display property following: [], template: "followers_list",});
creates render
method for you
<ul> {{#bind following}} <li data-guid="{{guid}}"> <a href="#!/{{username}}"> <img src="{{gravatar}}" /> </a> </li> {{/bind}}</ul>
Mustache++
Handlebars.js
{{#bind following}}
“Listen to changes in the following Array. If an element is added, render a new <li>. If an element is removed, remove it.
Syntax and impl are a
work in progress
Works for simple
properties
<div class="post"> <h1>{{bind title}}</h1> <div class="body">{{bind body}}</div></div>
What about getting
remote data?
Twitter.following = [];
$.getJSON("/following", function(json) { var users = json.users.map(function(post) { return Twitter.User.create(post); }); Twitter.set('following', users);});
Twitter.User?
Twitter.User = SC.Object.extend({ // documentation isFollowed: false, username: null, gravatar: null,
isFollowedChanged: function() { var followed = this.get('isFollowed');
if(followed) { Twitter.following.unshiftObject(this); } else { Twitter.following.removeObject(this); } }.observes('isFollowed')});
To Recap
Benefits: Isolation
$(".follow-me").live("click", function() { var link = $(this).parent().prev(); var count = parseInt($("#following span.count").text());
var newLink = $("<li class='user'>") .append(link.clone());
$("#following").prepend(newLink); $("#following span.count").text(count + 1);});
$(".follow-me").live("click", function() { var link = $(this).parent().prev(); var count = parseInt($("#following span.count").text());
var newLink = $("<li class='user'>") .append(link.clone());
$("#following").prepend(newLink); $("#following span.count").text(count + 1);}); X
Makes totally rewriting
parts of the view feasible
Makes totally rewriting
parts of the view trivial
Keeps data model
concerns out of the view
Makes revising large areas of the view simpler
I Haven't Touched on Controllers
This is a very simple
example
Controllers add view
concerns to objects
e.g. ArrayController has 'selection'
Mockup Ideas
amber-mockups.strobeapp.com
Thanks!