The road to Ember 2.0

Filippo Zanella
Filippo ZanellaFounder at Sellf
THE ROAD TO EMBER 2.0
FIRST EMBER.JS TREVISO MEETUP
presented by /Filippo Zanella @r4m
HURRY UP!
On July 24th Ember.js will bump to version 2.0.
The core team is moving fast (one release per monthly sprint)
Apr 4th v1.11.1, May 13th v1.12, June 12th v1.13.
...BUT DON'T BE SCARED.
Version 2.0 marks the transformation of Ember from simply an MVC
framework to a complete front-end stack.
Luckily, Ember 2.0 is not a big-bang rewrite. Staying on the
cutting-edge can be done without rewriting your app.
Changes have been rolled out incrementally. The 2.0 release will
simply remove features that have been deprecated.
MOTIVATIONS
STABILITY WITHOUT STAGNATION
In the greater JavaScript community, getting the latest and
greatest often means rewriting parts of your apps once a year.
The Ember community works hard to introduce new ideas with an
eye towards migration. The Ember core-team call this "stability
without stagnation".
When breaking changes are absolutely necessary, they try to make
those changes ones you can apply without too much thought. They
call these "mechanical" refactors.
To further aid in these transitions, a new tab to the Ember
Inspector that will list all deprecations in your application.
BIG BETS
The first bet was on open standards: JavaScript modules, promises
and Web Components.
The second bet was that the community was tired of hand-rolling
their own build scripts for each project. They've invested heavily in
Ember CLI, giving us a single tool that unifies the community and
provides a venue for disseminating great ideas.
In Ember 2.0, Ember CLI and ES6 modules will become first-class
parts of the Ember experience.
That is, you should begin moving your app to Ember CLI now.
LEARNING FROM COMMUNITY
Ember core-team have analyzed and discussing React's approach
to data flow and rendering and in particular how they make use of a
"virtual DOM" to improve performance.
Ember's view layer is one of the oldest parts of Ember, and was designed for a world where IE7 and IE8 were
dominant (gosh!). They've spent the better part of 2014 rethinking the view layer to be more DOM-aware, and the
new codebase (codenamed "HTMLBars") borrows the best ideas from React.
React's "virtual DOM" abstraction also allowed them to simplify the
programming model of component-based applications.
In Ember 2.0, a "virtual DOM" and data flow model has been
adopted to simplifies communication between components.
SIMPLIFYING EMBER CONCEPTS
Ember 2.0 is about simplification, to reduce file sizes, reduce code
complexity, and generally make apps easier to maintain.
The high-level set of improvements that we have planned are:
More intuitive attribute bindings
New HTML syntax for components
Block parameters for components
More consistent template scope
1-way data binding by default, with opt-in to 2-way bindings
More explicit communication between components
Routes drive components, instead of controller + template
Improved actions that are invoked inside components
NEW FEATURES
INLINE IF
In v1.11 Ember's ifhelper can be used in the inline form:
{{if isEnabled 'active' 'disabled'}}
EACH WITH INDEX
The eachhelper will support an indexblock param in v1.11:
{{#each people as |person index|}}
{{!-- The first index value will be 0 --}}
<div>{{index}}: {{person.name}}</div>
{{/each}}
BOUND ATTRIBUTE SYNTAX
Current Ember developers are familiar with the bind-attr
syntax, used to declare an attribute binding on an HTML element.
<a {{bind-attr href=url}}>Click here</a>
Ember 1.11 introduces a more intuitive API for attribute binding.
For example, here the color variable is bound to the class of a div:
<div class="{{color}}"></div>
The inline if helper can also be used in these contexts:
<div class="{{color}} {{if isEnabled 'active' 'disabled'}}"></div>
For some attributes, like the disabled boolean, passing a literal
value is desirable. An example:
<input disabled={{isDisabled}}>
COMPONENT HELPER
Ember components can be bound via the componenthelper. For
example this logic in a template:
{{#if isRed}}
{{x-red}}
{{else if isBlue}}
{{x-blue}}
{{else if isGreen}}
{{x-green}}
{{/if}}
Can be replaced by a property and the componenthelper.
{{component colorComponentName}}
The property colorComponentNameshould either have a value
of x-red, or x-blueetc. As the value of the computed property
changes, the rendered component will also change.
STORE.UNLOADALL()
Previously, store.unloadAllrequired a modelNameargument
to unload records of a type. Now, you can unload all records
without calling store.destroy.
@store.unloadAll()can now unload all models when not
passed a model name.
GLIMMER
Ember 1.13 is the first release that includes the new Glimmer
rendering engine. Glimmer is:
A new faster rendering engine that is especially fast at updates.
An implementation of the React-inspired "just re-render it"
programming model for components, with one-way data flow by
default and better enforcement for data-down, actions-up.
Supports ergonomic attributes (<my-link href="
{{url}}.html">go home</my-link>), angle-bracket
components (<my-component />), that hews closely to HTML
syntax with a few small enhancements.
THE ATTRSPROPERTY
Beginning with Ember 1.13 a component's attributes will be
available in this.attrsrather than on the component itself.
So when a component is invoked this way:
{{my-component title=model.name}}
The component will see this.attrs.titleas the current value
of model.name. Whenever model.namechanges via
observation, or when the parent component is re-rendered, my-
component's lifecycle hooks will be triggered, and it will see a new
version of model.name.
THE MUTHELPER
What if you want to allow the child component to modify the
property explicitly? The muthelper will produce an object that
contains both a valueproperty and an updatemethod.
In Ember 1.13, you can write:
{{my-counter count=(mut activatedCount)}}
Component.extend
click: ->
this.attrs.count.update(this.attrs.count.value + 1)
The call to {{mut activatedCount}}packages up an object
containing both its current value and a callback that allows the
receiving component to modify it.
CLOSURE ACTION
In Ember 1.x, the actions system used bubbling to pass user
behavior to a parent scope. E.g., when clicking a button an action
might bubble through several controllers.
Action bubbling was difficult to debug, and plagued by an inability
to have a return value.
Ember 2.x is component-driven, and replaces action bubbling
with a function-passing solution.
Actions:
Can be passed multiple arguments
Return a value. E.g. result = this.attrs.submit()
Can curry
CLOSURE ACTION
For example, action submitis passed to my-componentwhere it
is called upon click:
app/controllers/index.coffee
`import Ember from 'ember'`
Ember.Controller.extend
actions:
setName: (name) ->
model.set('name', name)
{{! app/templates/index.hbs }}
{{my-component submit=(action 'setName')}}
app/components/my-component.coffee
`import Ember from 'ember'`
Ember.Component.extend
click: ->
this.attrs.submit(this.get('name'))
NEW EMBER.JS HELPER API
Ember helpers:
Represent a single value
Do not manage DOM or control flow
Can recompute themselves
Can optionally access services
Do not require a dash
app/helpers/full-name.js
` `
Ember.Helper.helper (params, hash) ->
return params.join(' ')
import Ember from 'ember'
{{full-name "Daniel" model.lastName}}
{{my-component name=(full-name model.firstName "Smith")}}
{{! The following usage would set the model.name to the new full name
when my-component calls the submit action. }}
{{my-component submit=(action (mut model.name) (full-name model.firstName "Smith"
DEPRECATIONS
MORE CONSISTENT HANDLEBARS SCOPE
In Ember 1.9, the context-shifting forms of #eachand #withhave
been deprecated in favor of the named-parameter forms.
{{#each post in posts}}
{{!-- the context in here is the same as the outside context,
and `post` references the current iteration --}}
{{/each}}
{{#each posts}}
{{!-- the context in here has shifted to the individual post.
the outer context is no longer accessible --}}
{{/each}}
{{#with post as otherPost}}
{{!-- the context in here is the same as the outside context --}}
{{/with}}
{{#with post}}
{{!-- the context in here has shifted to the post.
the outer context is no longer accessible --}}
{{/with}}
MORE CONSISTENT HANDLEBARS SCOPE
In Ember 1.12, the inand assyntax are further deprecated in favor
of block params syntax.
To transition your code to the new syntax, you can change
templates that look like this:
{{#each people}}
<p>{{firstName}} {{lastName}}</p>
<p>{{address}}</p>
{{/each}}
with:
{{#each people itemController="abc" as |person|}}
<p>{{person.firstName}} {{person.lastName}}</p>
<p>{{person.address}}</p>
{{/each}}
OBJECTCONTROLLER
Experienced Ember users have enjoyed the use of proxying
behavior in the Ember.ObjectControllerclass since 1.0.
However, this behavior will be removed in Ember 2.0 as the
framework migrates to routable components.
OBJECTCONTROLLER
To migrate from an explicitly defined object controller, first convert
the class definition to inherit from Ember.Controller. E.g.:
import Ember from "ember";
// Change:
export default Ember.ObjectController.extend({
// To:
export default Ember.Controller.extend({
// ...
Next update any use of {{modelPropertyName}}in templates
with {{model.modelPropertyName}}. You should also review
any computed property dependent keys, observer keys, and get
and setstatements on the route and controller.
INSTANCES INITIALIZERS
Before FastBoot, you would only ever run applications one at a
time. In FastBoot, it is important for a single node server to be able
to serve a second request while the first one is fetching its data.
In Ember.js 1.12 application boot is separated into two phases:
Application initializers run, to register dependencies and
injections. These initializers are doing work that is shared across
all FastBoot requests, and therefore should not create instances.
Instance initializers run next. This is the right time to do work
that is specific to each FastBoot request. You can create
instances and modify their state here.
ACCESS TO INSTANCES IN INITIALIZERS
Previously, initializers had access to an object that allowed them to
both register new classes and get instances of those classes.
If you have an initializer that gets instances of a class, you need to
change it to use an instance initializer.
The store service is now injected as an . As a consequence, if you had initializers depending on
the store, you should move them to an instance initializer as well, and mark it as after: 'ember-data'.
instanceInitializer
ACCESS TO INSTANCES IN INITIALIZERS
Change code that looks like this:
App.initializer
name: "clock"
initialize: (container, application) ->
application.register("clock:main", Clock)
clock = container.lookup("clock:main")
clock.setStartTime(Date.now())
To:
App.initializer
name: "clock"
initialize: (registry, application) ->
application.register("clock:main", Clock)
App.instanceInitializer
name: "clock"
initialize: (instance) ->
clock = instance.container.lookup("clock:main")
clock.setStartTime(Date.now())
SHARED GETTER AND SETTER
Ember.js 1.12 introduces an improved syntax for computed
properties with a setter. Previously, computed properties with a
setter implemented that setter by inspecting the number of
arguments passed to the computed property's descriptor.
For example, this computed property splits a full name into two
parts when set:
fullName: Ember.computed "firstName", "lastName", (key, newName) ->
if (arguments.length > 1)
parts = newName.split(" ")
this.setProperties({ firstName: parts[0], lastName: parts[1] })
return newName
else
return this.get("firstName") + " " + this.get("lastName")
SHARED GETTER AND SETTER
These uses should be converted to use the new discrete getter and
setter syntax introduced in 1.12:
fullName: Ember.computed("firstName", "lastName", {
get: function() {
return this.get("firstName") + " " + this.get("lastName");
},
set: function(key, newName) {
var parts = newName.split(" ");
this.setProperties({ firstName: parts[0], lastName: parts[1] });
return newName;
}
});
EMBER.VIEW
Ember 1.x encouraged a Model-View-Controller-Route architecture.
Since then, the web has consolidated around a Model-Component-
Route pattern for web development that Ember 2.0 also embraces.
Views are removed from the Ember 2.0 API.
YES, VIEWS ARE REMOVED.
However a single release is likely insufficient for large apps to
upgrade their entire codebase away from routeable views, and
consequently Ember is providing extended support for views via
the addon.
This addon will remain compatible with Ember until v2.4 of the framework is released.
ember-legacy-views
EMBER.VIEW
In most cases Ember views can be replaced with a component. E.g.:
app/templates/show-menu.hbs
{{view.title}}
app/views/show-menu.coffee
` `
# Usage: {{view "show-menu"}}
Ember.View.extend
templateName: 'some-menu'
title: 'My Menu'
import Ember from 'ember'
Can be replaced with this component:
app/templates/components/show-menu.hbs
{{title}}
app/components/show-menu.coffee
` `
# Usage: {{show-menu}}
Ember.Component.extend
title: 'My Menu'
import Ember from 'ember'
EMBER.VIEW
Note that a component has always its own context in a template.
A view's template may have had access to other variables that were
present where it was called, such as a controller.
A component template will always be isolated, and if data is
needed it should be passed upon invocation. For example:
{{show-menu options=controller.menuOptions}}
EMBER.VIEW
ROUTABLE VIEWS
Currently, when a template for a given route is rendered, if there is
a view with the same name that view will also be used.
For example this view is attached to the rendered route template:
app/router.coffee
` `
Ember.Router.map ->
this.route('about')
import Ember from 'ember'
app/views/about.coffee
` `
Ember.View.extend
classNameBindings: ['controller.isActive:active']
import Ember from 'ember'
EMBER.VIEW
ROUTABLE VIEWS
There are only two reasons a view may be used for a route:
To set attribute bindings
To attach event handlers
To manage all the jquery stuffs
You should migrate away from routed views.
EMBER.VIEW
ROUTABLE VIEWS
For example to attach bindings to an element in the template is
sufficient:
app/router.coffee
` `
Ember.Router.map ->
this.route('about')
import Ember from 'ember'
app/templates/about.hbs
<div class="{{if isActive 'active'}}">
<!-- something something -->
</div>
EMBER.VIEW
ROUTABLE VIEWS
If attaching events or sharing DOM is necessary, consider a
component:
app/templates/about.hbs
{{#active-layout isActive=isActive}}
<!-- something something -->
{{/active-layout}}
app/components/active-layout.js
` `
Ember.Component.extend
classNameBindings: ['isActive:active']
click: ->
# Handle click
import Ember from 'ember'
EMBER.VIEW
NOTABLE
In preparation for Ember 2.0, 1.13 introduces many deprecations.
Some of these include:
All view APIs in Ember (Ember.CoreView, Ember.View,
Ember.CollectionView, Ember.ContainerView)
Options to the {{#eachhelper that trigger a legacy and poorly
performing legacy layer. Like: itemView, itemViewClass,
tagName, emptyViewand emptyViewClass.
The itemControllerargument for {{#each.
The viewand viewClassparams for {{outlet}}
EMBER.LINKVIEW
As a consequence of the deprecation of Ember.View, many
internal views have been ported to component.
Ember.LinkView, the class that backs the {{link-to}}
helper, have been ported to Ember.LinkComponent.
Most uses of Ember.LinkViewcan be directly ported to the
Ember.LinkComponentclass.
EMBER.SELECT
Using the Ember.Selectglobal and its view helper form
({{view 'select'}}) is deprecated.
Ember.Selectis implemented in a legacy coding style that uses
patterns such as observers and two-way data binding that:
can cause pathological performance problems
provide an experience that is not consistent with idiomatic
Ember 2.0 development.
Sadly true. Complex Ember.Selectwith mixed dynamic content are tricky to be managed.
Legacy support will be provided via the addon.ember-legacy-views
EMBER.SELECT
Ember 2.0 provides several new features that make it much more
straightforward to implement </select>tag functionality via the
data-down, actions-up paradigm in one's codebase.
For example, to create a component that displays a prompt and a
list of dropdown options, the following code could be used:
app/templates/components/my-select.hbs
<select {{action 'change' on='change'}}>
{{#each content key="@index" as |item|}}
<option value="{{item}}" selected={{is-equal item selectedValue}}>
{{item}}
</option>
{{/each}}
</select>
EMBER.SELECT
app/components/my-select.js
` `
Ember.Component.extend
content: []
selectedValue: null
actions:
change: ->
changeAction = this.get('action')
selectedElement = this.$('select')[0]
selectedIndex = selectedElement.selectedIndex
content = this.get('content')
selectedValue = content[selectedIndex]
this.set('selectedValue', selectedValue)
changeAction(selectedValue)
import Ember from 'ember'
app/helpers/is-equal.js
` `
Ember.Helper.helper ([leftSide, rightSide]) ->
return leftSide === rightSide
import Ember from 'ember'
EMBER.SELECT
This component could be used in a template by supplying it an
array of strings as contentand an action to call when the user
makes a selection as change:
app/templates/application.hbs
The currently selected item: {{mySelectedItem}}.
{{my-select content=myItems action=(action (mut mySelectedItem))}}
myItemsis an array of strings: ['one', 'two', ...].
This uses the `action`and `mut`helpers to pass in an action
that will update the (outer scope) `mySelectedItem`property
with the user's selection.
TYPEKEY TO MODELNAME
In Ember Data, when you ask for a model, Ember Data looks its
class up using Ember's API. When the model
class is looked up, Ember Data stores the type on the model class.
Dependency Injection
For example, when the following code runs in your application:
post = this.store.getById('post', 1)
and Ember Data will store the string "post" on the model class:
console.log(post.constructor.typeKey) # 'post'
Ember Data uses this typeKeyproperty internally when
creating/extracting payloads in Serializers, and when locating
models in Adapters.
TYPEKEY TO MODELNAME
In Ember Data 1.0.0-beta.18, the typeKeyproperty is now called
modelName. In addition, the modelNameis a dasherized string
(previously it was always normalized to be a camelCased string).
For example, if you had a model called TacoShop, it would be stored on the model's constructor's modelName
property as taco-shop, whereas previously it would be stored as tacoShop.
Accessing the typeKeyproperty should still work, but will trigger
deprecation warnings.
IE 8
Ember Data v1.0.0-beta.19 is the last release to support Internet
Explorer 8. Future versions of Ember Data will not support IE 8.
R.I.P.
RESOURCES
The road to Ember.js 2.0 RFC
The transition to Ember 2.0 in detail
Deprecations added in Ember 1.X
1 of 47

More Related Content

What's hot(20)

Learn react-jsLearn react-js
Learn react-js
C...L, NESPRESSO, WAFAASSURANCE, SOFRECOM ORANGE24.3K views
AngularJS Unit TestAngularJS Unit Test
AngularJS Unit Test
Chiew Carol871 views
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API
07.pallav657 views
Ember - introductionEmber - introduction
Ember - introduction
Harikrishnan C876 views
Introduction to React JSIntroduction to React JS
Introduction to React JS
Arno Lordkronos32.5K views
Introduction to react_jsIntroduction to react_js
Introduction to react_js
MicroPyramid .1.7K views
Simpletest - A beginners guideSimpletest - A beginners guide
Simpletest - A beginners guide
Ed Conolly890 views
Test Driven Development with JavaFXTest Driven Development with JavaFX
Test Driven Development with JavaFX
Hendrik Ebbers16.5K views
Dan Webb PresentationDan Webb Presentation
Dan Webb Presentation
RubyOnRails_dude596 views
Spring bootSpring boot
Spring boot
Bhagwat Kumar2.4K views
Usability in the GeoWebUsability in the GeoWeb
Usability in the GeoWeb
Dave Bouwman32.4K views
Debugging JavascriptDebugging Javascript
Debugging Javascript
SolTech, Inc.998 views
Building a Backend with FlaskBuilding a Backend with Flask
Building a Backend with Flask
Make School8.8K views

Similar to The road to Ember 2.0(20)

-Kotlin_Camp_Unit2.pptx-Kotlin_Camp_Unit2.pptx
-Kotlin_Camp_Unit2.pptx
RishiGandhi196 views
-Kotlin Camp Unit2.pptx-Kotlin Camp Unit2.pptx
-Kotlin Camp Unit2.pptx
IshwariKulkarni638 views
Workshop 16: EmberJS Parte IWorkshop 16: EmberJS Parte I
Workshop 16: EmberJS Parte I
Visual Engineering695 views
Migration from Rails2 to Rails3Migration from Rails2 to Rails3
Migration from Rails2 to Rails3
Umair Amjad1.2K views
ReactJS.pptxReactJS.pptx
ReactJS.pptx
SamyakShetty220 views
Delivering with ember.jsDelivering with ember.js
Delivering with ember.js
Andrei Sebastian Cîmpean420 views
React js - The Core ConceptsReact js - The Core Concepts
React js - The Core Concepts
Divyang Bhambhani3.1K views
The road to Ember.js 2.0The road to Ember.js 2.0
The road to Ember.js 2.0
Codemotion838 views
Full slidescr16Full slidescr16
Full slidescr16
Lucio Grenzi317 views
React context  React context
React context
Seven Peaks Speaks126 views
React js programming conceptReact js programming concept
React js programming concept
Tariqul islam1.4K views
Paper trail gemPaper trail gem
Paper trail gem
Bacancy Technology321 views
React hooksReact hooks
React hooks
Ramy ElBasyouni956 views
Content-Driven Apps with ReactContent-Driven Apps with React
Content-Driven Apps with React
Netcetera1.1K views
Javascript functionsJavascript functions
Javascript functions
Alaref Abushaala816 views

Recently uploaded(20)

The road to Ember 2.0

  • 1. THE ROAD TO EMBER 2.0 FIRST EMBER.JS TREVISO MEETUP presented by /Filippo Zanella @r4m
  • 2. HURRY UP! On July 24th Ember.js will bump to version 2.0. The core team is moving fast (one release per monthly sprint) Apr 4th v1.11.1, May 13th v1.12, June 12th v1.13.
  • 3. ...BUT DON'T BE SCARED. Version 2.0 marks the transformation of Ember from simply an MVC framework to a complete front-end stack. Luckily, Ember 2.0 is not a big-bang rewrite. Staying on the cutting-edge can be done without rewriting your app. Changes have been rolled out incrementally. The 2.0 release will simply remove features that have been deprecated.
  • 5. STABILITY WITHOUT STAGNATION In the greater JavaScript community, getting the latest and greatest often means rewriting parts of your apps once a year. The Ember community works hard to introduce new ideas with an eye towards migration. The Ember core-team call this "stability without stagnation". When breaking changes are absolutely necessary, they try to make those changes ones you can apply without too much thought. They call these "mechanical" refactors. To further aid in these transitions, a new tab to the Ember Inspector that will list all deprecations in your application.
  • 6. BIG BETS The first bet was on open standards: JavaScript modules, promises and Web Components. The second bet was that the community was tired of hand-rolling their own build scripts for each project. They've invested heavily in Ember CLI, giving us a single tool that unifies the community and provides a venue for disseminating great ideas. In Ember 2.0, Ember CLI and ES6 modules will become first-class parts of the Ember experience. That is, you should begin moving your app to Ember CLI now.
  • 7. LEARNING FROM COMMUNITY Ember core-team have analyzed and discussing React's approach to data flow and rendering and in particular how they make use of a "virtual DOM" to improve performance. Ember's view layer is one of the oldest parts of Ember, and was designed for a world where IE7 and IE8 were dominant (gosh!). They've spent the better part of 2014 rethinking the view layer to be more DOM-aware, and the new codebase (codenamed "HTMLBars") borrows the best ideas from React. React's "virtual DOM" abstraction also allowed them to simplify the programming model of component-based applications. In Ember 2.0, a "virtual DOM" and data flow model has been adopted to simplifies communication between components.
  • 8. SIMPLIFYING EMBER CONCEPTS Ember 2.0 is about simplification, to reduce file sizes, reduce code complexity, and generally make apps easier to maintain. The high-level set of improvements that we have planned are: More intuitive attribute bindings New HTML syntax for components Block parameters for components More consistent template scope 1-way data binding by default, with opt-in to 2-way bindings More explicit communication between components Routes drive components, instead of controller + template Improved actions that are invoked inside components
  • 10. INLINE IF In v1.11 Ember's ifhelper can be used in the inline form: {{if isEnabled 'active' 'disabled'}}
  • 11. EACH WITH INDEX The eachhelper will support an indexblock param in v1.11: {{#each people as |person index|}} {{!-- The first index value will be 0 --}} <div>{{index}}: {{person.name}}</div> {{/each}}
  • 12. BOUND ATTRIBUTE SYNTAX Current Ember developers are familiar with the bind-attr syntax, used to declare an attribute binding on an HTML element. <a {{bind-attr href=url}}>Click here</a> Ember 1.11 introduces a more intuitive API for attribute binding. For example, here the color variable is bound to the class of a div: <div class="{{color}}"></div> The inline if helper can also be used in these contexts: <div class="{{color}} {{if isEnabled 'active' 'disabled'}}"></div> For some attributes, like the disabled boolean, passing a literal value is desirable. An example: <input disabled={{isDisabled}}>
  • 13. COMPONENT HELPER Ember components can be bound via the componenthelper. For example this logic in a template: {{#if isRed}} {{x-red}} {{else if isBlue}} {{x-blue}} {{else if isGreen}} {{x-green}} {{/if}} Can be replaced by a property and the componenthelper. {{component colorComponentName}} The property colorComponentNameshould either have a value of x-red, or x-blueetc. As the value of the computed property changes, the rendered component will also change.
  • 14. STORE.UNLOADALL() Previously, store.unloadAllrequired a modelNameargument to unload records of a type. Now, you can unload all records without calling store.destroy. @store.unloadAll()can now unload all models when not passed a model name.
  • 15. GLIMMER Ember 1.13 is the first release that includes the new Glimmer rendering engine. Glimmer is: A new faster rendering engine that is especially fast at updates. An implementation of the React-inspired "just re-render it" programming model for components, with one-way data flow by default and better enforcement for data-down, actions-up. Supports ergonomic attributes (<my-link href=" {{url}}.html">go home</my-link>), angle-bracket components (<my-component />), that hews closely to HTML syntax with a few small enhancements.
  • 16. THE ATTRSPROPERTY Beginning with Ember 1.13 a component's attributes will be available in this.attrsrather than on the component itself. So when a component is invoked this way: {{my-component title=model.name}} The component will see this.attrs.titleas the current value of model.name. Whenever model.namechanges via observation, or when the parent component is re-rendered, my- component's lifecycle hooks will be triggered, and it will see a new version of model.name.
  • 17. THE MUTHELPER What if you want to allow the child component to modify the property explicitly? The muthelper will produce an object that contains both a valueproperty and an updatemethod. In Ember 1.13, you can write: {{my-counter count=(mut activatedCount)}} Component.extend click: -> this.attrs.count.update(this.attrs.count.value + 1) The call to {{mut activatedCount}}packages up an object containing both its current value and a callback that allows the receiving component to modify it.
  • 18. CLOSURE ACTION In Ember 1.x, the actions system used bubbling to pass user behavior to a parent scope. E.g., when clicking a button an action might bubble through several controllers. Action bubbling was difficult to debug, and plagued by an inability to have a return value. Ember 2.x is component-driven, and replaces action bubbling with a function-passing solution. Actions: Can be passed multiple arguments Return a value. E.g. result = this.attrs.submit() Can curry
  • 19. CLOSURE ACTION For example, action submitis passed to my-componentwhere it is called upon click: app/controllers/index.coffee `import Ember from 'ember'` Ember.Controller.extend actions: setName: (name) -> model.set('name', name) {{! app/templates/index.hbs }} {{my-component submit=(action 'setName')}} app/components/my-component.coffee `import Ember from 'ember'` Ember.Component.extend click: -> this.attrs.submit(this.get('name'))
  • 20. NEW EMBER.JS HELPER API Ember helpers: Represent a single value Do not manage DOM or control flow Can recompute themselves Can optionally access services Do not require a dash app/helpers/full-name.js ` ` Ember.Helper.helper (params, hash) -> return params.join(' ') import Ember from 'ember' {{full-name "Daniel" model.lastName}} {{my-component name=(full-name model.firstName "Smith")}} {{! The following usage would set the model.name to the new full name when my-component calls the submit action. }} {{my-component submit=(action (mut model.name) (full-name model.firstName "Smith"
  • 22. MORE CONSISTENT HANDLEBARS SCOPE In Ember 1.9, the context-shifting forms of #eachand #withhave been deprecated in favor of the named-parameter forms. {{#each post in posts}} {{!-- the context in here is the same as the outside context, and `post` references the current iteration --}} {{/each}} {{#each posts}} {{!-- the context in here has shifted to the individual post. the outer context is no longer accessible --}} {{/each}} {{#with post as otherPost}} {{!-- the context in here is the same as the outside context --}} {{/with}} {{#with post}} {{!-- the context in here has shifted to the post. the outer context is no longer accessible --}} {{/with}}
  • 23. MORE CONSISTENT HANDLEBARS SCOPE In Ember 1.12, the inand assyntax are further deprecated in favor of block params syntax. To transition your code to the new syntax, you can change templates that look like this: {{#each people}} <p>{{firstName}} {{lastName}}</p> <p>{{address}}</p> {{/each}} with: {{#each people itemController="abc" as |person|}} <p>{{person.firstName}} {{person.lastName}}</p> <p>{{person.address}}</p> {{/each}}
  • 24. OBJECTCONTROLLER Experienced Ember users have enjoyed the use of proxying behavior in the Ember.ObjectControllerclass since 1.0. However, this behavior will be removed in Ember 2.0 as the framework migrates to routable components.
  • 25. OBJECTCONTROLLER To migrate from an explicitly defined object controller, first convert the class definition to inherit from Ember.Controller. E.g.: import Ember from "ember"; // Change: export default Ember.ObjectController.extend({ // To: export default Ember.Controller.extend({ // ... Next update any use of {{modelPropertyName}}in templates with {{model.modelPropertyName}}. You should also review any computed property dependent keys, observer keys, and get and setstatements on the route and controller.
  • 26. INSTANCES INITIALIZERS Before FastBoot, you would only ever run applications one at a time. In FastBoot, it is important for a single node server to be able to serve a second request while the first one is fetching its data. In Ember.js 1.12 application boot is separated into two phases: Application initializers run, to register dependencies and injections. These initializers are doing work that is shared across all FastBoot requests, and therefore should not create instances. Instance initializers run next. This is the right time to do work that is specific to each FastBoot request. You can create instances and modify their state here.
  • 27. ACCESS TO INSTANCES IN INITIALIZERS Previously, initializers had access to an object that allowed them to both register new classes and get instances of those classes. If you have an initializer that gets instances of a class, you need to change it to use an instance initializer. The store service is now injected as an . As a consequence, if you had initializers depending on the store, you should move them to an instance initializer as well, and mark it as after: 'ember-data'. instanceInitializer
  • 28. ACCESS TO INSTANCES IN INITIALIZERS Change code that looks like this: App.initializer name: "clock" initialize: (container, application) -> application.register("clock:main", Clock) clock = container.lookup("clock:main") clock.setStartTime(Date.now()) To: App.initializer name: "clock" initialize: (registry, application) -> application.register("clock:main", Clock) App.instanceInitializer name: "clock" initialize: (instance) -> clock = instance.container.lookup("clock:main") clock.setStartTime(Date.now())
  • 29. SHARED GETTER AND SETTER Ember.js 1.12 introduces an improved syntax for computed properties with a setter. Previously, computed properties with a setter implemented that setter by inspecting the number of arguments passed to the computed property's descriptor. For example, this computed property splits a full name into two parts when set: fullName: Ember.computed "firstName", "lastName", (key, newName) -> if (arguments.length > 1) parts = newName.split(" ") this.setProperties({ firstName: parts[0], lastName: parts[1] }) return newName else return this.get("firstName") + " " + this.get("lastName")
  • 30. SHARED GETTER AND SETTER These uses should be converted to use the new discrete getter and setter syntax introduced in 1.12: fullName: Ember.computed("firstName", "lastName", { get: function() { return this.get("firstName") + " " + this.get("lastName"); }, set: function(key, newName) { var parts = newName.split(" "); this.setProperties({ firstName: parts[0], lastName: parts[1] }); return newName; } });
  • 31. EMBER.VIEW Ember 1.x encouraged a Model-View-Controller-Route architecture. Since then, the web has consolidated around a Model-Component- Route pattern for web development that Ember 2.0 also embraces. Views are removed from the Ember 2.0 API. YES, VIEWS ARE REMOVED. However a single release is likely insufficient for large apps to upgrade their entire codebase away from routeable views, and consequently Ember is providing extended support for views via the addon. This addon will remain compatible with Ember until v2.4 of the framework is released. ember-legacy-views
  • 32. EMBER.VIEW In most cases Ember views can be replaced with a component. E.g.: app/templates/show-menu.hbs {{view.title}} app/views/show-menu.coffee ` ` # Usage: {{view "show-menu"}} Ember.View.extend templateName: 'some-menu' title: 'My Menu' import Ember from 'ember' Can be replaced with this component: app/templates/components/show-menu.hbs {{title}} app/components/show-menu.coffee ` ` # Usage: {{show-menu}} Ember.Component.extend title: 'My Menu' import Ember from 'ember'
  • 33. EMBER.VIEW Note that a component has always its own context in a template. A view's template may have had access to other variables that were present where it was called, such as a controller. A component template will always be isolated, and if data is needed it should be passed upon invocation. For example: {{show-menu options=controller.menuOptions}}
  • 34. EMBER.VIEW ROUTABLE VIEWS Currently, when a template for a given route is rendered, if there is a view with the same name that view will also be used. For example this view is attached to the rendered route template: app/router.coffee ` ` Ember.Router.map -> this.route('about') import Ember from 'ember' app/views/about.coffee ` ` Ember.View.extend classNameBindings: ['controller.isActive:active'] import Ember from 'ember'
  • 35. EMBER.VIEW ROUTABLE VIEWS There are only two reasons a view may be used for a route: To set attribute bindings To attach event handlers To manage all the jquery stuffs You should migrate away from routed views.
  • 36. EMBER.VIEW ROUTABLE VIEWS For example to attach bindings to an element in the template is sufficient: app/router.coffee ` ` Ember.Router.map -> this.route('about') import Ember from 'ember' app/templates/about.hbs <div class="{{if isActive 'active'}}"> <!-- something something --> </div>
  • 37. EMBER.VIEW ROUTABLE VIEWS If attaching events or sharing DOM is necessary, consider a component: app/templates/about.hbs {{#active-layout isActive=isActive}} <!-- something something --> {{/active-layout}} app/components/active-layout.js ` ` Ember.Component.extend classNameBindings: ['isActive:active'] click: -> # Handle click import Ember from 'ember'
  • 38. EMBER.VIEW NOTABLE In preparation for Ember 2.0, 1.13 introduces many deprecations. Some of these include: All view APIs in Ember (Ember.CoreView, Ember.View, Ember.CollectionView, Ember.ContainerView) Options to the {{#eachhelper that trigger a legacy and poorly performing legacy layer. Like: itemView, itemViewClass, tagName, emptyViewand emptyViewClass. The itemControllerargument for {{#each. The viewand viewClassparams for {{outlet}}
  • 39. EMBER.LINKVIEW As a consequence of the deprecation of Ember.View, many internal views have been ported to component. Ember.LinkView, the class that backs the {{link-to}} helper, have been ported to Ember.LinkComponent. Most uses of Ember.LinkViewcan be directly ported to the Ember.LinkComponentclass.
  • 40. EMBER.SELECT Using the Ember.Selectglobal and its view helper form ({{view 'select'}}) is deprecated. Ember.Selectis implemented in a legacy coding style that uses patterns such as observers and two-way data binding that: can cause pathological performance problems provide an experience that is not consistent with idiomatic Ember 2.0 development. Sadly true. Complex Ember.Selectwith mixed dynamic content are tricky to be managed. Legacy support will be provided via the addon.ember-legacy-views
  • 41. EMBER.SELECT Ember 2.0 provides several new features that make it much more straightforward to implement </select>tag functionality via the data-down, actions-up paradigm in one's codebase. For example, to create a component that displays a prompt and a list of dropdown options, the following code could be used: app/templates/components/my-select.hbs <select {{action 'change' on='change'}}> {{#each content key="@index" as |item|}} <option value="{{item}}" selected={{is-equal item selectedValue}}> {{item}} </option> {{/each}} </select>
  • 42. EMBER.SELECT app/components/my-select.js ` ` Ember.Component.extend content: [] selectedValue: null actions: change: -> changeAction = this.get('action') selectedElement = this.$('select')[0] selectedIndex = selectedElement.selectedIndex content = this.get('content') selectedValue = content[selectedIndex] this.set('selectedValue', selectedValue) changeAction(selectedValue) import Ember from 'ember' app/helpers/is-equal.js ` ` Ember.Helper.helper ([leftSide, rightSide]) -> return leftSide === rightSide import Ember from 'ember'
  • 43. EMBER.SELECT This component could be used in a template by supplying it an array of strings as contentand an action to call when the user makes a selection as change: app/templates/application.hbs The currently selected item: {{mySelectedItem}}. {{my-select content=myItems action=(action (mut mySelectedItem))}} myItemsis an array of strings: ['one', 'two', ...]. This uses the `action`and `mut`helpers to pass in an action that will update the (outer scope) `mySelectedItem`property with the user's selection.
  • 44. TYPEKEY TO MODELNAME In Ember Data, when you ask for a model, Ember Data looks its class up using Ember's API. When the model class is looked up, Ember Data stores the type on the model class. Dependency Injection For example, when the following code runs in your application: post = this.store.getById('post', 1) and Ember Data will store the string "post" on the model class: console.log(post.constructor.typeKey) # 'post' Ember Data uses this typeKeyproperty internally when creating/extracting payloads in Serializers, and when locating models in Adapters.
  • 45. TYPEKEY TO MODELNAME In Ember Data 1.0.0-beta.18, the typeKeyproperty is now called modelName. In addition, the modelNameis a dasherized string (previously it was always normalized to be a camelCased string). For example, if you had a model called TacoShop, it would be stored on the model's constructor's modelName property as taco-shop, whereas previously it would be stored as tacoShop. Accessing the typeKeyproperty should still work, but will trigger deprecation warnings.
  • 46. IE 8 Ember Data v1.0.0-beta.19 is the last release to support Internet Explorer 8. Future versions of Ember Data will not support IE 8. R.I.P.
  • 47. RESOURCES The road to Ember.js 2.0 RFC The transition to Ember 2.0 in detail Deprecations added in Ember 1.X