EmberJS
Dev @thoughtworks
suchitpuri.com
Property Valuation Engine
What We Wanted
-
Wanted to build single page app.
- Team with Ruby on Rails experience so the framework should fit in well.
-
Build something modular and robust.
-
Framework should encourage good design principles and promote reuse
What we Decided
EmberJS
-
Javascript Web Application Framework
-
Based On Model View Controller
-
Designed For Single Page Web Application
-
More Of Convention Over Configuration
- Plugs in really well with rails active model serializers
Who Is Using Ember
Ember Object Model
- Objects and Instances
- Inheritance
- Composition
Objects and Instances
All "Objects" in Ember inherit from Ember.Object. This is the building block for just about everything in Ember.
It adds in methods like create , destroy , extend , addObserver, reOpen
var myObject = Ember.Object.create({
firstName: 'Suchit',
lastName: 'Puri'
});
myObject.set('firstName', 'Something');
myObject.get('firstName'); // Something
Inheritance
var Person = Ember.Object.extend({
firstName: '',
lastName: '',
sayName: function() {
console.log(this.get('firstName') + ' ' +
this.get('lastName');
}
});
var myPerson = Person.create({
firstName: 'Suchit',
lastName: 'Puri'
});
myPerson.sayName(); // Suchit Puri
Composition With Mixins
App.Focusable = Ember.Mixin.create({
focusIn: function() {
this.clearMessages();
},
change: function() {
this.valid();
},
focusOut: function() {
this.change();
} }); App.TextField = Ember.View.extend( App.Focusable {
valid: function(value) {
var rules = this.get("rules");
this.evaluateRules(rules, value);
}
}
Computed Properties
-
Methods that can be accessed as properties
- Allows us to propagate changes through our application We can specify our dependent properties that trigger an update
var Person = Ember.Object.extend({ firstName: '', lastName: '', fullName: function() { return this.get('firstName') + ' ' + this.get('lastName'); }.property('firstName') }); var myPerson = Person.create({ firstName: 'Suchit', lastName: 'Puri' }); myPerson.get('fullName'); // Suchit Puri
Observers
Ember MVC
Router
Ember Router allows you to map out each of your application’s states into a hierarchical structure as well as the paths that your user can travel through your application.
Router
- Traslate URL into nested templates backed by a controller and a model.
- Represent Application State as URL
- Update controller, model and make it available to templates
Router
App.Router.map(function() {
this.resource('posts', function() {
this.route('new');
});
});
URL | Route Name | Controller | Route | Template |
---|---|---|---|---|
/ |
index |
IndexController |
IndexRoute |
index |
N/A |
posts 1
|
PostsController |
PostsRoute |
posts |
/posts |
posts.index |
PostsController ↳ PostsIndexController
|
PostsRoute ↳ PostsIndexRoute
|
posts ↳ posts/index
|
/posts/new |
posts.new |
PostsController ↳ PostsNewController
|
PostsRoute ↳ PostsNewRoute
|
posts ↳ posts/new
|
Router
loading route
App.ApplicationRoute = Ember.Route.extend({
actions: {
loading: function() {
var view = this.container.lookup('view:loading').append();
this.router.one('didTransition', view, 'destroy');
}
}
});
Ember Controllers
In Ember.js, controllers allow you to decorate your models with display logic. In general, your models will have properties that are saved to the server, while controllers will have properties that your app does not need to save to the server.
Model-Controller-Template
Coupling
Event Bubbling
Views And Components
-
When you need sophisticated handling of user events
-
When you want to create a re-usable component
Views
<html>
<head>
<script type="text/x-handlebars" data-template-name="say-hello">
Hello, <b>{{view.name}}</b>
</script>
</head>
</html>
var view = Ember.View.create({
templateName: 'say-hello',
name: "Bob"
click: function(evt) {
alert("ClickableView was clicked!");
}
});
Ember Components
- it's such a good idea that the W3C is currently working on the Custom Elements spec.
- Ember's implementation of components hews as closely to the Web Components specification as possible
Ember Components
Ember Data
Ember Data is a library for robustly managing model data in your Ember.js applications.
Ember Data is designed to be agnostic to the underlying persistence mechanism, so it works just as well with JSON APIs over HTTP as it does with streaming WebSockets or local IndexedDB storage.
Store
DS Model
App.Person = DS.Model.extend({
firstName: DS.attr('string'),
birthday: DS.attr('date')
});
App.Order = DS.Model.extend({ lineItems: DS.hasMany('lineItem') });
App.LineItem = DS.Model.extend({
order: DS.belongsTo('order') });
Data Adapters
App.PhotoRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('photo', params.photo_id);
}
});
Action | HTTP Verb | URL |
---|---|---|
Find | GET | /photos/123 |
Find All | GET | /photos |
Update | PUT | /photos/123 |
Create | POST | /photos |
Delete | DELETE | /photos/123 |
Data Adapters
var attr = DS.attr,
hasMany = DS.hasMany,
belongsTo = DS.belongsTo;
App.Post = DS.Model.extend({
title: attr(),
comments: hasMany('comment'),
});
App.Comment = DS.Model.extend({
body: attr()
});
{
"post": {
"id": 1,
"title": "Rails is omakase",
"comments": ["1", "2"],
"user" : "dhh"
},
"comments": [{
"id": "1",
"body": "Rails is unagi"
}, {
"id": "2",
"body": "Omakase O_o"
}]
}
Ember Data Example
Ember Testing
Testing is a core part of the Ember framework and its development cycle.
EmberJs has good support for unit and integration tests which integrates well with CI
Qunit is the default framework chosen by EmberJs for testing but it integrates well with other frameworks well
EmberJS Testing
Questions ?
EmberJS in Action
By Suchit Puri
EmberJS in Action
- 5,647