Upload
jtrapp07
View
4.392
Download
1
Tags:
Embed Size (px)
DESCRIPTION
Ember.js is a front end JavaScript MVC framework, but probably won't map to the exact same MVC patterns as CakePHP does on the server side. I cover the major features of Ember.js and attempt to make the connection to CakePHP classes where it applies.
Citation preview
EMBER.JS FOR ACAKEPHPDEVELOPER
EMBER.JSA framework for creating ambitious web applications.
1.0 RELEASED!
OBJECTS
EXTENDING/CREATING OBJECTSvar Person, p;
Person = Ember.Object.extend({ sayHello: function() { alert('Hello!'); }});
p = Person.create();
p.sayHello();
DATA BINDINGSvar 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 PROPERTIESvar 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 NameRoute this.resource('projects');Route (class) App.ProjectsRouteController App.ProjectsControllerView App.ProjectsViewTemplate 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 FILESIntegrate 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 aspart 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 ROUTESApp.Router.map(function() { this.route('about'); // #/about});
Routes defined this way can not contain nested routes
DEFINING RESOURCESApp.Router.map(function() { this.resource('conferences'); // #/conferences});
Will render the conferences template in theapplication templates outlet.
NESTING RESOURCESApp.Router.map(function() { this.resource('conferences', function() { // #/conferences this.resource('cakefest'); // #/conferences/cakefest });});
Will render the cakefest template in the conferencestemplates outlet, which is rendered in the application
templates outlet.
DYNAMIC SEGMENTSApp.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 ROUTESApp.Router.map(function() { this.resource('conferences', function() { // #/conferences this.route('new'); // #/conferences/new });});
Renders conferences/new template in theconferences templates outlet.
ROUTES
DEFINING DATA FOR TEMPLATEwindow.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 CLASSESApp.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 ); }});
TEMPLATESconferences.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 CALLBACKSApp.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.
CONTROLLERDecorates 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 CONTROLLERActs like an object and proxies to the model property.// In route class (this is the default behavior)setupController: function(controller, model) { controller.set('model', model);}
// Object ControllerApp.ConferenceController = Ember.ObjectController.extend({ isEven: function() { return this.get('name').length % 2 === 0; }.property('name')});
isEven calls this.get('name') which proxies tothis.get('model.name')
ARRAY CONTROLLERActs like an array, but actually performs on the methods
on the model property.App.ConferencesController = Ember.ArrayController.extend({ sortProperties: ['title']});
// conferences template{{#each conf in controller}} <div> <h1>{{conf.title}}</h1> </div>{{/each}}
Looping over controller in a template is actuallylooping over the model property*
VIEWS
Views are primarily used to handle browser events. Sincemany application actions can be handled with the action
helper and controller methods, you'll often not defineviews.
UTILIZE BROWSER EVENTSApp.ConferenceView = App.View.extend({ click: function(e) { alert('Click event was handled'); }});
SETTING VIEWS TAGIn the DOM, your templates are wrapped by a div with a
special id that Ember knows about.App.ConferenceView = Ember.View.extend({ tagName: 'section',});
The element wrapping the template will now be asection
HELPERS
REUSABLE TEMPLATE FUNCTIONSEmber.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