forked from emberjs/emberjs.github.com
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Tom Dale
committed
Jan 24, 2012
0 parents
commit e10866d
Showing
51 changed files
with
32,956 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<html><body><h1>File Not Found</h1><p>/docs/application/index.html</p></body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Ember.js Guide | ||
|
||
## Understanding MVC Architecture | ||
1. What is MVC? | ||
2. The Model Layer | ||
3. The View Layer | ||
4. The Controller Layer | ||
5. Augmenting Controllers with Storyboards | ||
|
||
9. Mixins | ||
10. Arrays and Enumerables | ||
11. Understanding the Run Loop | ||
5. Describing Your UI with Handlebars | ||
1. What is Handlebars? | ||
2. Displaying Templates | ||
3. Handlebars In-Depth | ||
4. Ember.View | ||
5. The View Rendering Pipeline | ||
6. Form Helpers | ||
6. Handling User Events | ||
1. Implementing Handlers on Views | ||
2. Event Bubbling | ||
3. Registering Custom Events | ||
4. Customizing Ember.Application | ||
7. Testing | ||
1. What is unit testing? | ||
2. What is integration testing? | ||
3. Using Jasmine | ||
4. Mocking Events and Remote Services | ||
5. Run Loop Considerations | ||
8. Getting Data into Your App | ||
1. Content TBD | ||
9. Managing Assets and Deploying to Production | ||
1. Multiple Files and Dependency Resolution | ||
2. Concatenation | ||
3. Minification | ||
4. Deploying Static Assets: Best Practices | ||
5. Profiling for Performance |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<html><body><h1>File Not Found</h1><p>/docs/enumerables/index.html</p></body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<html><body><h1>File Not Found</h1><p>/docs/handlebars/index.html</p></body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<html><body><h1>File Not Found</h1><p>/docs/introduction/index.html</p></body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<html><body><h1>File Not Found</h1><p>/docs/object_model/index.html</p></body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<html><body><h1>File Not Found</h1><p>/docs/views/index.html</p></body> |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
App = SC.Application.create(); | ||
|
||
/* | ||
Model | ||
*/ | ||
|
||
App.Contact = SC.Object.extend({ | ||
firstName: '', | ||
lastName: '', | ||
|
||
hasName: function() { | ||
var firstName = this.get('firstName'), | ||
lastName = this.get('lastName'); | ||
|
||
return firstName !== '' || lastName !== ''; | ||
}.property('firstName', 'lastName') | ||
}); | ||
|
||
/* | ||
Controllers | ||
*/ | ||
|
||
App.contactsController = SC.ArrayController.create({ | ||
// The array of Contact objects that backs the array controller. | ||
content: [], | ||
|
||
// The content array, sorted by first name, or last | ||
// name if no first name is provided. | ||
sortedContacts: function() { | ||
var content = this.get('content'); | ||
|
||
return content.slice().sort(function(a, b) { | ||
var firstNameA = a.get('firstName'), | ||
firstNameB = b.get('firstName'); | ||
|
||
if (!firstNameA) { | ||
firstNameA = a.get('lastName'); | ||
} | ||
|
||
if (!firstNameB) { | ||
firstNameB = b.get('lastName'); | ||
} | ||
|
||
if (!firstNameA && firstNameB) { return 1; } | ||
if (!firstNameB && firstNameA) { return -1; } | ||
if (firstNameA < firstNameB) { return -1; } | ||
if (firstNameA > firstNameB) { return 1; } | ||
return 0; | ||
}); | ||
|
||
// Every time a contact's first name or last name changes, | ||
// recompute the order. Since this is a somewhat expensive | ||
// operation, the cacheable() flag means that the computed | ||
// value will be automatically memoized. | ||
}.property('@each.firstName', '@each.lastName').cacheable(), | ||
|
||
// Creates a new, empty Contact object and adds it to the | ||
// array controller. | ||
newContact: function() { | ||
this.pushObject(App.Contact.create({ | ||
phoneNumbers: [] | ||
})); | ||
}, | ||
|
||
loadContacts: function() { | ||
var self = this; | ||
$.ajax({ | ||
url: '/contacts.json', | ||
dataType: 'json', | ||
success: function(data) { | ||
var contacts = data.contacts; | ||
|
||
// Turn JSON objects into bindable Ember | ||
// objects. | ||
contacts = contacts.map(function(item) { | ||
return self.createContactFromJSON(item); | ||
}); | ||
|
||
self.set('content', contacts); | ||
}, | ||
|
||
error: function() { | ||
self.pushObject(self.createContactFromJSON({ | ||
firstName: 'Peter', | ||
lastName: 'Wagenet', | ||
phoneNumbers: ['(415) 555-2381'] | ||
})); | ||
|
||
self.set('isFromFixtures', true); | ||
} | ||
}); | ||
}, | ||
|
||
createContactFromJSON: function(json) { | ||
json.phoneNumbers = json.phoneNumbers.map(function(number) { | ||
return { number: number }; | ||
}); | ||
|
||
return App.Contact.create(json); | ||
} | ||
}); | ||
|
||
App.contactsController.loadContacts(); | ||
|
||
App.selectedContactController = SC.Object.create({ | ||
content: null | ||
}); | ||
|
||
App.DeleteNumberView = SC.View.extend({ | ||
classNames: ['delete-number-view'], | ||
click: function() { | ||
var phoneNumber = this.get('content'); | ||
var contact = this.getPath('contentView.content'); | ||
|
||
contact.get('phoneNumbers').removeObject(phoneNumber); | ||
} | ||
}); | ||
|
||
App.EditField = SC.View.extend({ | ||
tagName: 'span', | ||
templateName: 'edit-field', | ||
|
||
doubleClick: function() { | ||
this.set('isEditing', true); | ||
return false; | ||
}, | ||
|
||
focusOut: function() { | ||
this.set('isEditing', false); | ||
}, | ||
|
||
keyUp: function(evt) { | ||
if (evt.keyCode === 13) { | ||
this.set('isEditing', false); | ||
} | ||
} | ||
}); | ||
|
||
App.TextField = SC.TextField.extend({ | ||
didInsertElement: function() { | ||
this.$().focus(); | ||
} | ||
}); | ||
|
||
SC.Handlebars.registerHelper('editable', function(path, options) { | ||
options.hash.valueBinding = path; | ||
return SC.Handlebars.helpers.view.call(this, App.EditField, options); | ||
}); | ||
|
||
SC.Handlebars.registerHelper('button', function(options) { | ||
var hash = options.hash; | ||
|
||
if (!hash.target) { | ||
hash.target = "App.contactsController"; | ||
} | ||
return SC.Handlebars.helpers.view.call(this, SC.Button, options); | ||
}); | ||
|
||
App.ContactListView = SC.View.extend({ | ||
classNameBindings: ['isSelected'], | ||
|
||
click: function() { | ||
var content = this.get('content'); | ||
|
||
App.selectedContactController.set('content', content); | ||
}, | ||
|
||
isSelected: function() { | ||
var selectedItem = App.selectedContactController.get('content'), | ||
content = this.get('content'); | ||
|
||
if (content === selectedItem) { return true; } | ||
}.property('App.selectedContactController.content') | ||
}); | ||
|
||
App.CardView = SC.View.extend({ | ||
contentBinding: 'App.selectedContactController.content', | ||
classNames: ['card'], | ||
|
||
addPhoneNumber: function() { | ||
var phoneNumbers = this.getPath('content.phoneNumbers'); | ||
phoneNumbers.pushObject({ number: '' }); | ||
} | ||
}); | ||
|
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Ember.js Contacts</title> | ||
<link rel="stylesheet" href="style.css" type="text/css" media="screen" charset="utf-8"> | ||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script> | ||
<script type="text/javascript" src="../lib/ember.min.js"></script> | ||
<script type="text/javascript" src="app.js"></script> | ||
</head> | ||
<body> | ||
<div id="container"> | ||
<div id="contact-list"> | ||
<script type="text/x-handlebars"> | ||
<h2>My Contacts</h2> | ||
<ul> | ||
{{#each App.contactsController.sortedContacts}} | ||
{{#view App.ContactListView contentBinding="this"}} | ||
{{#with content}} | ||
<li> | ||
{{#if hasName}} | ||
<b>{{firstName}}</b> {{#if firstName}}{{lastName}}{{else}}<b>{{lastName}}</b>{{/if}} | ||
{{else}} | ||
<span class="no-name">no name</span> | ||
{{/if}} | ||
{{/with}} | ||
{{/view}} | ||
{{/each}} | ||
</ul> | ||
{{#button action="newContact"}}New Contact{{/button}} | ||
</script> | ||
</div> | ||
|
||
<div id="detail"> | ||
<script type="text/x-handlebars"> | ||
{{#if App.selectedContactController.content}} | ||
{{#view App.CardView}} | ||
<div class="name"> | ||
{{editable "content.firstName"}} {{editable "content.lastName"}} | ||
</div> | ||
|
||
<table class="phone-numbers"> | ||
{{#each content.phoneNumbers}} | ||
<tr> | ||
<td>{{editable number}}</td> | ||
<td>{{view App.DeleteNumberView contentBinding="this"}}</td> | ||
</tr> | ||
{{/each}} | ||
</table> | ||
{{#view SC.Button target="contentView" action="addPhoneNumber"}} | ||
Add Phone Number | ||
{{/view}} | ||
{{/view}} | ||
{{else}} | ||
<div class="no-contact-selected">No contact selected.</div> | ||
{{/if}} | ||
|
||
</script> | ||
</div> | ||
|
||
<script type="text/x-handlebars" data-template-name="edit-field"> | ||
{{#if isEditing}} | ||
{{view App.TextField valueBinding="value" propagatesEvents=true}} | ||
{{else}} | ||
{{#if value}} | ||
{{value}} | ||
{{else}} | ||
<span class="no-name">empty</span> | ||
{{/if}} | ||
{{/if}} | ||
</script> | ||
</body> | ||
</html> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
var express = require('express'), | ||
connect = require('connect'); | ||
|
||
var app = express.createServer( | ||
connect.logger(), | ||
connect.static(__dirname), | ||
connect.static('..') | ||
); | ||
|
||
var guid = 0; | ||
|
||
var contacts = [ | ||
{ | ||
guid: ++guid, | ||
firstName: 'Peter', | ||
lastName: 'Wagenet', | ||
phoneNumbers: ['(415) 555-2380'] | ||
}, | ||
|
||
{ | ||
guid: ++guid, | ||
firstName: 'Yehuda', | ||
lastName: 'Katz', | ||
phoneNumbers: ['(415) 555-6666'] | ||
}, | ||
|
||
{ | ||
guid: ++guid, | ||
firstName: 'Erik', | ||
lastName: 'Bryn', | ||
phoneNumbers: ['(415) 555-2380', '(614) 555-8127'] | ||
}, | ||
|
||
{ | ||
guid: ++guid, | ||
firstName: 'James', | ||
lastName: 'Rosen', | ||
phoneNumbers: ['(415) 555-2380'] | ||
}, | ||
|
||
{ | ||
guid: ++guid, | ||
firstName: 'Kara', | ||
lastName: 'Gates', | ||
phoneNumbers: ['(207) 555-3141'] | ||
}, | ||
|
||
{ | ||
guid: ++guid, | ||
firstName: 'Dudley', | ||
lastName: 'Flanders', | ||
phoneNumbers: ['(415) 555-6789'] | ||
}, | ||
|
||
{ | ||
guid: ++guid, | ||
firstName: 'Tom', | ||
lastName: 'Dale', | ||
phoneNumbers: ['(808) 800-8135'] | ||
} | ||
]; | ||
|
||
app.get('/contacts.json', function(req, res) { | ||
res.send({contacts: contacts}); | ||
}); | ||
|
||
app.listen(3000); |
Oops, something went wrong.