getting into ember.js
DESCRIPTION
A talk I gave on Ember at AngleBrackets in Orlando in April, 2014.TRANSCRIPT
Getting into Ember.js
Rey Bango@reybango
http://emberjs.com/
Abstract Complexities
MVC Component relationships Client-side templating Binding Caching Leverage existing frameworks when possible
jQuery (DOM)
Handlebars (templates)
Opinionated
A little history
Experienced Team
Yehuda KatzCreator of MerbRails Core TeamjQuery Core Team
Tom DaleApple MobileMe/iCloud
SproutCore Team
http://www.discourse.org/
https://github.com/discourse/discourse
Let’s take a look…
Who is Ember for?
Good Dynamic apps
Desktop-like feel
Very little page refresh
Not Good Static sites
Blogs
Little user interaction
What We’ll Cover
Core concepts of the framework Naming conventions
Routers
Templates
Models
Controllers
A basic app
What We Won’t Cover
Ember vs Angular vs Knockout vs Kendo vs …
What We Won’t Cover
Ember Data
Is It "Production Ready™"?
No. The API should not be considered stable until 1.0. Breaking changes, and how to update accordingly, are listed in TRANSITION.md.
Core Concepts
Application Object
Application namespace Add event listeners to the document Automatically creates default components Automatically renders the application
template
var App = Ember.Application.create({});
Application Object
Route object: App.ApplicationRoute Controller: App.ApplicationController View: App.ApplicationView Template: application
var App = Ember.Application.create({});
Let’s take a look…
Ember Inspector
Browser add-on for Chrome & Firefox See your routes Inspect your objects Ember Data records
LoggingApp = Ember.Application.create({ LOG_TRANSITIONS: true});
Let’s take a look…
Naming Conventions
Ties components together Minimizes code Allows Ember to do its magic Learn them to make your life easier!!!
Naming Conventions
Route object: App.ApplicationRoute Controller: App.ApplicationController View: App.ApplicationView Template: application
var App = Ember.Application.create({});
Naming Conventions
Route object: App.EmployeesRoute Controller: App.EmployeesController View: App.EmployeesView Template: employees
this.resource( 'employees' );
Naming Conventions
Not part of the Ember API De facto community standard
var App = Ember.Application.create({});
What’s up with “App”?
The Router
The router manages the state of the application
Manages the location-specific routes
Marshalls request for resources to the appropriate location
Like a traffic cop directing traffic
App.Router.map( function() {…});
Routes
Takes us to “/#/about” Like the streets of your app Location-specific The URL is the key identifier Define the resources needed as a user navigates the
app e.g.: a model that requests data
this.resource( 'about' );
Routes
App.Router.map( function() {
this.resource( accounts' ); // Takes us to ”/#/accounts“ this.resource( ‘gallery‘ ); // Takes us to ”/#/gallery“
});
Route Aliases
http://embertalk:8888/#/aboutus References the ‘about’ route
this.resource( 'about’, { path: ‘/aboutus’ });
Route Objects
Do the heavy lifting for the routes Customize the behavior of a route Interface with models and controllers
App.GalleryRoute = Ember.Route.extend({
model: function() { return App.GalleryPics.findAll();}
});
Let’s take a look…
Templates
Client-side parsed via JavaScript Uses the Handlebars framework Special directives act as placeholders for data
<script type=“text/x-handlebars” data-template-name=“sayhello”>
Hello, <strong>{{firstName}} {{lastName}}</strong>!
</script>
Templates
<script type=“text/x-handlebars” data-template-name=“sayhello”>
Hello, <strong>{{firstName}} {{lastName}}</strong>!
</script>
Template ExpressionsLooping - {{#each}} directive:
<ul> {{#each friend in model}} <li>{{friend.name}} is my friend</li> {{/each}}<ul>
Template ExpressionsConditional Expressions – {{#if…}} directive:
{{#if person}} Welcome back, <b>{{person.firstName}} {{person.lastName}}</b>!{{else}} Please log in.{{/if}}
Template ExpressionsConditional Expressions – Can you do this?:
{{#if age >= 18}} {{person.firstName}}, you’re technically an adult!{{else}} Sorry youngster. Ask your parents for permission.{{/if}}
Template ExpressionsConditional Expressions - Computed Property:
isOld: function() { return this.get('age') > 45;}.property()
{{#each person in model itemController='person'}} <li>{{person.firstName}}, {{person.age}} {{#if isOld}} – Ready for Centrum Silver!{{/if}}</li>{{/each}}
Template ExpressionsBind attributes to HTML elements:
<img {{bindAttr src="link.thumbnailUrl"}} />
Renders this:
<img src=“kitten.png">
Can’t I just do this?
<img src={{link.thumbnailUrl}} />
Template ExpressionsLinks:
{{#link-to 'about'}}About{{/link-to}}
Links to a route created in the router like this:
this.resource( 'about' );
Template Expressions
HTML Tags:
<ul> {{#link-to 'about’ tagName=‘li’}}About{{/link-to}}</ul>
Styling:
{{#link-to 'about’ class=“navitem”}}About{{/link-to}}
{{outlet}}
Special placeholder for other templates
<script type="text/x-handlebars" data-template-name="application">
{{outlet}}
</script>
Let’s take a look…
Models
Interface with external APIs Data is typically stored as JSON Two ways to define them:
Subclass of Ember.Object
Ember Data
App.RedditLink = Ember.Object.extend({…});
Modelshttp://www.reddit.com/r/cute/.json
{ "kind": "Listing", "data": { "modhash": "a1vty6l4kkc8e96de61136a717e96531a997ebdd8e36180519", "children": [{ "kind": "t3", "data": { "domain": "imgur.com", "banned_by": null, "media_embed": {}, "subreddit": "cute", "selftext_html": null, "selftext": "", "likes": null, "link_flair_text": null, "id": "1b7h10", "clicked": false, "title": "First Easter away from my Mom, she still makes it special.", "media": null, "score": 6, "approved_by": null, "over_18": false, "hidden": false, "thumbnail": "http://f.thumbs.redditmedia.com/63tG_KTJIGF_Vwq5.jpg", "subreddit_id": "t5_2qh5l", "edited": false, "link_flair_css_class": null, "author_flair_css_class": null, "downs": 2, "saved": false,
Models
App.RedditLink = Ember.Object.extend({});
App.RedditLink.reopenClass({
findAll: function() {
var links = [];
$.getJSON("http://www.reddit.com/r/cute/.json?jsonp=?").then(function(response) {
response.data.children.forEach(function (child) {
links.pushObject(App.RedditLink.create(child.data));
});
});
return links; }
});
Models
App.GalleryRoute = Ember.Route.extend({
model: function() { return
App.RedditLink.findAll();}
}); Links my model to the route & controller for the Gallery URL When a user goes to /gallery, the model is now available with data model is a keyword. It’s a hook between the route, controller & the
model
Controllers
Represent data from the model Can store other data that needs to
persist Templates are connected to controllers Controllers may know of a model but
not the other way around Created for you automatically if you
don’t define one
Controllers
App.GalleryRoute = Ember.Route.extend({
setupController: function(controller) {
controller.set('content', ['red', 'yellow', 'blue']);
}
});
Controllers
App.GalleryController = Ember.ObjectController.extend({
// the initial value of the `search` propertysearch: ’lastname’, isAnimal: function() { return this.get(’pictype') === ‘animal’; }.property()
});
Let’s take a look…
Ember Reddit Demo…
Online Resources
http://emberjs.comhttp://discuss.emberjs.comhttp://handlebarsjs.comhttp://emberwatch.com
Ember Online Learning
http://bit.ly/CStrialenrollment
$9/First Month
Follow these peeps
@wycats@tomdale@trek@wagenet@evil_trout@codinghorror@commadelimited@emberwatch
Fin…