Ritesh Keswani
Panasonic Avionics
Twitter: @bmbrcp
Components
Glimmer
Routes
Computed Property
HTMLBars
Initializers
Services
Templates
Bindings
Model
URL drives the state of the application
Nested routes
Index route
Dynamic segments
Reset namespace
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('posts', function() {
this.route('new');
this.route('comments', { resetNamespace: true }, function() {
this.route('new');
});
});
this.route('post', { path: '/post/:post_id' });
this.route('page-not-found', { path: '/*.*' });
});
export default Router;
Maps a URL to a route
Model hooks
Render different template
Setup Controller
Transition events
import Ember from 'ember';
export default Ember.Route.extend({
myStore: Ember.inject.service('my-store'),
model: function(params) {
var allRuns = this.get('myStore').getAllRuns();
return allRuns.findBy("id", Number(params.id));
},
actions : {
close: function() {
this.transitionTo('index');
}
}
});
Sets data on a controller, renders templates
HTML
Handlebars/HTMLBars
Glimmer
Backed with a context
The {{outlet}} helper
Data binding
Helpers
<div class="row">
{{#each model as |run|}}
<div class="col-xs-6 col-md-3">
{{#link-to 'details' run class="thumbnail"}}
<img src={{run.image}} alt={{run.location}}>
<h3 style="text-align:center">{{run.name}}</h3>
{{/link-to}}
</div>
{{/each}}
</div>
Describes the user interface of the application
Handlebars
HTMLBars
Bring logic into Ember templating
Several built-in helpers
Inline, Nested and Block invocations
Custom helpers
Stateless by default
{{#if person}}
Welcome back
{{else}}
Please log in.
{{/if}}
{{#unless hasPaid}}
You owe: ${{total}}
{{/unless}}
<ul>
{{#each people as |person|}}
<li>Hello, {{person.name}}!</li>
{{/each}}
</ul>
{{#each-in people as |name person|}}
Hello, {{name}}! You are {{person.age}} years old.
{{else}}
Sorry, nobody is here.
{{/each-in}}
{{#link-to "photos.photo.edit" 1}}
First Photo Ever
{{/link-to}}
W3C's Custom Elements spec
Backed by an element
Isolated Views
The {{component}} helper
Data down, actions up
Wrap jQuery widgets
{{#each model as |post|}}
{{#blog-post title=post.title}}
{{post.body}}
{{/blog-post}}
{{/each}}
Application-specific HTML tag, implements behavior using JavaScript
<article class="blog-post">
<h1>{{title}}</h1>
<p>{{yield}}</p>
<p>Edit title: {{input type="text" value=title}}</p>
</article>
export default Ember.Component.extend({
actions: {
hello: function(name) {
console.log("Hello", name);
}
}
});
Almost deprecated
Query params
Routing
Managing dependencies
export default Ember.Controller.extend({
queryParams: ['category'],
category: null,
postController: Ember.inject.controller('post'),
actions: {
toggleBody() {
this.toggleProperty('isExpanded');
}
}
});
Manages state, binds data
Lazy loaded
Inject into any object
From initializer or Ember.inject
Examples: Ember Data, User/session authentication
export default Ember.Service.extend({
items: [],
add(item) {
this.get('items').pushObject(item);
},
remove(item) {
this.get('items').removeObject(item);
},
empty() {
this.get('items').setObjects([]);
}
});
Singleton that represents application-wide state
Provides a class system
Mixins
Enumerables
Computed properties
Observers
Person = Ember.Object.extend({
helloWorld() {
alert('Hi, my name is ' + this.get('name'));
},
// these will be supplied by `create`
firstName: null,
lastName: null,
fullName: Ember.computed('firstName', 'lastName', function() {
return `${this.get('firstName')} ${this.get('lastName')}`;
})
});
var ironMan = Person.create({
firstName: 'Tony',
lastName: 'Stark'
});
ironMan.get('fullName'); // "Tony Stark"
Supports observation of property value changes