EMBER.JS FOR A
CAKEPHP
DEVELOPER
EMBER.JS
A framework for creating ambitious web applications.
1.0 RELEASED!
OBJECTS
EXTENDING/CREATING OBJECTS
var Person, p;
Person = Ember.Object.extend({
sayHello: function() {
alert('Hello!');
}
});
p = Person.create();
p.sayHello();
DATA BINDINGS
var Person, p;
Person = Ember.Object.extend({
message: 'Hello',
responseBinding: 'message',
yell: function() {
alert(this.get('response'));
}
});
p = Person.create();
p.yell(); // alert('Hello')
p.set('message', 'Goodbye');
p.yell(); // alert('Goodbye')
COMPUTED PROPERTIES
var Person, p;
Person = Ember.Object.extend({
firstName: '',
lastName: '',
fullName: function() {
return this.get('firstName') + ' ' + this.get('lastName');
}.property('firstName', 'lastName')
});
p = Person.create({ firstName: 'Joey', lastName: 'Trapp' });
p.get('fullName'); // "Joey Trapp"
p.set('firstName', 'Connor');
p.get('fullName'); // "Connor Trapp"
CONVENTIONS
Type Name
Route this.resource('projects');
Route (class) App.ProjectsRoute
Controller App.ProjectsController
View App.ProjectsView
Template Ember.TEMPLATES['projects']
TEMPLATES
TEMPLATES EMBEDDED IN HTML
<script type="text/x-handlebars" data-template-name="project">
<h1>{{title}}</h1>
<p>{{description}}</p>
</script>
Gets compiled on document read to:
Ember.TEMPLATES['project'] = // compiled template function
TEMPLATES FILES
Integrate into build step and compile server side
// webroot/templates/projects/add.hbs
<form {{action save on="submit"}}>
<label>Project Name</label>
{{input type="text" value=name}}
<input type="submit" value="Save">
</form>
Gets compiled with a build tool in development, and as
part of a production build step to:
Ember.TEMPLATES['projects/add'] = // compiled template function
BUILT IN HELPERS
<div class="posts">
{{#each post in controller}}
{{#if post.isPublished}}
<h2>{{#link-to 'post' post}} {{post.title}} {{/link-to}}</h2>
{{/if}}
{{else}}
<p>{{#link-to 'posts.new'}}Create the first post{{/link-to}}
{{/each}}
</p></div>
And many more
ROUTER
DEFINING ROUTES
App.Router.map(function() {
this.route('about'); // #/about
});
Routes defined this way can not contain nested routes
DEFINING RESOURCES
App.Router.map(function() {
this.resource('conferences'); // #/conferences
});
Will render the conferencestemplate in the
applicationtemplates outlet.
NESTING RESOURCES
App.Router.map(function() {
this.resource('conferences', function() { // #/conferences
this.resource('cakefest'); // #/conferences/cakefest
});
});
Will render the cakefesttemplate in the conferences
templates outlet, which is rendered in the application
templates outlet.
DYNAMIC SEGMENTS
App.Router.map(function() {
this.resource('conferences', function() { // #/conferences
this.resource('conference', { path: ':name' }); // #/conferences/blah
});
});
By default, the segment value is available in the template.
// conference template
<h1>{{name}}</h1>
<p>...</p>
NESTED ROUTES
App.Router.map(function() {
this.resource('conferences', function() { // #/conferences
this.route('new'); // #/conferences/new
});
});
Renders conferences/newtemplate in the
conferencestemplates outlet.
ROUTES
DEFINING DATA FOR TEMPLATE
window.CONFERENCES = [
Em.Object.create({id: 1, name: 'cakefest' }),
Em.Object.create({id: 2, name: 'embercamp' }),
Em.Object.create({id: 3, name: 'jsconf' })
];
var App = Ember.Application.create();
App.Router.map(function() {
this.resource('conferences', function() {
this.resource('conference', { path: '/:conference_id' });
});
});
DEFINING ROUTE CLASSES
App.ConferencesRoute = Ember.Route.extend({
model: function() {
return window.CONFERENCES;
}
});
App.ConferenceRoute = Ember.Route.extend({
model: function(params) {
return window.CONFERENCES.findProperty(
'id',
+params.conference_id
);
}
});
TEMPLATES
conferences.hbs
<h1>Conferences</h1>
{{#each conf in controller}}
{{#link-to 'conference' conf}} {{conf.name}} {{/link-to}}
{{/each}}
conference.hbs
<h1>{{name}} Conference</h1>
<p>{{desc}}</p>
OTHER CALLBACKS
App.ConferenceRoute = Ember.Route.extend({
model: function(params) {
// Return data for the template
},
setupController: function(controller, model) {
// Receives instance of this controller and
// the return value from model hook
},
renderTemplate: function() {
// Render template manually if you need to do
// something unconventional
}
});
CONTROLLERS
Controllers are long lived in Ember*,
and are the default context for templates.
CONTROLLER
Decorates a model, but has no special proxying behavior.
App.ApplicationController = Ember.Controller.extend({
search: '',
query: function() {
var query = this.get('search');
this.transitionToRoute('search', { query: query });
}
});
OBJECT CONTROLLER
Acts like an object and proxies to the modelproperty.
// In route class (this is the default behavior)
setupController: function(controller, model) {
controller.set('model', model);
}
// Object Controller
App.ConferenceController = Ember.ObjectController.extend({
isEven: function() {
return this.get('name').length % 2 === 0;
}.property('name')
});
isEvencalls this.get('name')which proxies to
this.get('model.name')
ARRAY CONTROLLER
Acts like an array, but actually performs on the methods
on the modelproperty.
App.ConferencesController = Ember.ArrayController.extend({
sortProperties: ['title']
});
// conferences template
{{#each conf in controller}}
<div>
<h1>{{conf.title}}</h1>
</div>
{{/each}}
Looping over controllerin a template is actually
looping over the modelproperty*
VIEWS
Views are primarily used to handle browser events. Since
many application actions can be handled with the action
helper and controller methods, you'll often not define
views.
UTILIZE BROWSER EVENTS
App.ConferenceView = App.View.extend({
click: function(e) {
alert('Click event was handled');
}
});
SETTING VIEWS TAG
In the DOM, your templates are wrapped by a divwith a
special id that Ember knows about.
App.ConferenceView = Ember.View.extend({
tagName: 'section',
});
The element wrapping the template will now be a
section
HELPERS
REUSABLE TEMPLATE FUNCTIONS
Ember.Handlebars.helper('capitalize', function(str) {
return str[0].toUpperCase() + str.slice(1);
});
And use the helpers in handlebars templates
<h1>{{title}}</h1>
<p>by {{capitalize firstName}} {{capitalize lastName}}</p>
QUESTIONS?
@joeytrapp
github.com/joeytrapp
@loadsys
github.com/loadsys

Ember.js for a CakePHP Developer