Skip to content

Instantly share code, notes, and snippets.

@wycats
Created October 4, 2011 21:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wycats/1262837 to your computer and use it in GitHub Desktop.
Save wycats/1262837 to your computer and use it in GitHub Desktop.
/**
* This gist illustrates how you can use placeholder objects to
* abstract the mechanism by which information becomes available
* from the need to update the DOM when it does.
*
* Note: the current release of SproutCore uses .property(), not
* .dependsOn() as in this example.
*/
// The Person object exposes firstName, lastName and fullName and
// isLoaded to other objects. It is may asynchronously populate
// those properties but listeners don't have to know exactly how
// that population will occur
App.Person = SC.Object.extend({
// firstName delegates to the data hash
firstNameBinding: 'data.firstName',
// lastName delegates to the data hash
lastNameBinding: 'data.lastName',
// fullName just uses the object's firstName and lastName;
// it is isolated from the asynchrony of the initial load
fullName: function() {
return this.get('firstName') + ' ' + this.get('lastName')
}.dependsOn('firstName', 'lastName'),
// returns true if the firstName and lastName are present.
// this computed property is isolated from how exactly
// those properties are populated. If they are populated
// initially, isLoaded will always be true.
isLoaded: function() {
return this.get('firstName') && this.get('lastName');
}.dependsOn('firstName', 'lastName'),
// load in the person from Ajax and populate the data
// property when done.
load: function(id) {
var self = this;
$.getJSON("/people/" + id, function(json) {
this.set('data', json.person);
});
return this;
}
});
// A PersonView represents a Person in the DOM. It is totally isolated
// from the way that the Person's properties are loaded.
App.PersonView = SC.View.extend({
render: function(buffer) {
// Is the person ready to be represented in the DOM. If not, just
// insert an empty <div> wrapper.
if (this.getPath('person.isLoaded')) {
buffer.push("<p>" + this.getPath('person.fullName') + "</p>");
}
},
// when the Person object becomes loaded, or its full name changed,
// update the view's representation in the DOM.
personChanged: function() {
if (this.getPath('person.isLoaded') { this.rerender(); }
}.observes('person.isLoaded', 'person.fullName')
});
var person = App.Person.create().load(12);
var personView = App.PersonView.create({ person: person });
personView.appendTo('#some-node');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment