Share
Embed
How to learn Ember
My presentation at EmberNYC Meetup on How to learn Ember - Getting Started, State & Debugging
Taras Mankovski
March 28, 2014
Transcript
46 slides
-
About me • Real name Taras Mankovski • @EmberSherpa on
Twitter • Full-time Ember Developer from August 2013 • Previous experience - PHP & Python -
About you • bunch of server side • maybe native
• enough JavaScript -
Integration into existing project Video: Integrating Ember.js into Existing Applications
by James Croft • Ember app as separate project • Compile assets • Install like a jQuery plugin -
Will it work with my backend? Is your API jQuery.ajax
compatible? • Ember works purely via API • Unaffected by what’s underneath • jsonapi.com +1 -
Project Layout Starter Kit Ember CLI Resolver Namespace File Based
Dependencies Included Bower Asset Compiler None Broccoli.js Testing qUnit qUnit with Testem runner ECMAScript 6 modules ✗ ✓ Server ✗ ✓ Continuous Integration ✗ ✓ -
The Router • Manages transitions between states • URL ===
serialized state • Converts url into state -
What the hell is State? State is collection of active
objects in memory. -
How is state created? When you say, Ember Assumes •
SearchRoute & SearchController • SearchIndexRoute & SearchIndexController • ApplicationRoute & ApplicationController • SearchErrorRoute & SearchErrorController • SearchLoadingRoute & SearchLoadingController Router.map(function() { this.resource(‘search’); }); Objects are created based on conventions -
Objects generated from container Videos • Containers and Dependency Injection
in Ember by Matthew Beale • How to Call A From B in Ember by Ben Donaldson App = Ember.Application.create({ LOG_ACTIVE_GENERATION: true }); -
Back to the Router Router.map(function() { this.resource(‘search’); }); • map
urls to routes • tells what objects to initialize for the url -
State in Ember Applications Route Controller View model • fetch
data from api setupController • setup state prepare state State • binds state to template • converts DOM events into state actions present state -
Route App.SearchRoute = Ember.Route.extend({ model: function() { /* models for
state */ }, setupController: function(controller, models) { controller.set(‘content’, models); // other initial state }, renderTemplate: function() { this.render(); } }); -
Rendered, now what? • Objects live in memory • Just
sitting there • Until an event triggers an action -
State Actions <button {{action ’search’}}>Search</button> 1. View converts DOM event
into action 2. Action bubbles up state hierarchy 3. Stops when handler is found -
Ember Way App.SearchController = Ember.Controller.extend({ actions: { search: function() {
if (this.get(‘isValid’)) { this.transitionToRoute(‘search.index’, keyword’); } } }, isValid: function() { return !Em.isEmpty(this.get(‘keyword’)); }.property(‘keyword’) }); -
Computed Properties • functions that look like values • recalculates
when read & invalidated • invalidated when dependent property changes -
DOM vs State centric thinking DOM Centric State Centric 1.
that happens 2. check this, do that mechanics handled by your code value driven 1. when this value is 2. that value should be action driven mechanics handled by Ember Bindings -
Bonus Simpler code, better user experience <button {{action=’search’}} {{bind-attr disabled=isNotValid}}>Search</button>
App.SearchController = Ember.Controller.extend({ ... isNotValid: Em.computed.not(‘isValid’) }); API Docs: Ember Computed Macros -
CPs are fast but not synchronous Ember aggregates property changes
<button {{action 'search'}} {{bind-attr disabled=isNotValid}}>Search</button> In Template In Controller Method this.set(‘keyword’, ‘ember’); this.set(‘keyword’, ‘is’); this.set(keyword, ‘great’); -
The Run Loop Guide: The Run Loop Video: The Ember
Run Loop by Jason Madsen Built in Queues • sync • actions • routeTransitions • render • afterRender • destroy Useful Functions • Em.run • Em.run.later • Em.run.scheduleOnce • Em.run.debounce • Em.run.throttle -
Promises Value will be returned later App.SearchIndexRoute = Ember.Route.extend({ model:
function(params) { return ic.ajax(‘/search/’+params.keyword) .then(function(posts){}, function(error){}); }}); ic-ajax: https://github.com/instructure/ic-ajax by Ryan Florence Guide: Loading / Error Substates Video: The Promise Land by Stefan Penner -
RSVP.js Library: https://github.com/tildeio/rsvp.js/ Em.RSVP.all() Em.RSVP.hash() Microlib that powers Ember’s Promises
model: function() { var p1 = ic.ajax(‘posts/1’), p2 = ic.ajax(‘posts/10’); return Em.RSVP.all([ p1, p2 ]); } model: function() { return Em.RSVP.hash({ post: ic.ajax(‘posts/1’), comments: ic.ajax(‘posts/1/comments’) }); } -
The Plan 1. Identify the problem 2. Isolate the problem
3. Make it better -
Identify the problem 1. Console 2. Purple button 3. debugger;
4. Ember Inspector -
Console Activate Debugging flags var App = Ember.Application.extend({ LOG_ACTIVE_GENERATION: true,
// log generated controllers & routes LOG_TRANSITIONS: true, // Basic logging, e.g. "Transitioned into 'post'" LOG_TRANSITIONS_INTERNAL: true, // detailed logging LOG_VIEW_LOOKUPS: true // template and view being rendered }); -
Anonymous functions in Stacktrace • Most lines you won’t recognize
• 99% of problems are in your code • Name your functions so you recognize them -
Name your functions Bad Good var App.SearchResultsController = Em.ArrayController.extend({ authors:
function() { var content = this.get(‘content’); var authors = content.map(function(post){ return post.get(‘author’); }); }.property(‘content’) }); var App.SearchResultsController = Em.ArrayController.extend({ authors: function() { var content = this.get(‘content’); var authors = content.map(getAuthor); function getAuthor(post){ return post.get(‘author’); } }.property(‘content’) }); -
Ember Inspector Download: Chrome Extension or Firefox Addon Video: Introduction
to Ember Inspector by Stefan Penner -
Isolate the problem 1. Identify simples model of the problem
2. Create emberjs.jsbin.com 3. Ask on Stackoverflow or discuss.emberjs.com -
Make friends • Fastest way to learn is from others
• Attend Hacker Hours • Help each other