Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How to learn Ember

How to learn Ember

My presentation at EmberNYC Meetup on How to learn Ember - Getting Started, State & Debugging

Taras Mankovski

March 28, 2014
Tweet

More Decks by Taras Mankovski

Other Decks in Programming

Transcript

  1. About me • Real name Taras Mankovski • @EmberSherpa on

    Twitter • Full-time Ember Developer from August 2013 • Previous experience - PHP & Python
  2. 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
  3. 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
  4. 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 ✗ ✓
  5. The Router • Manages transitions between states • URL ===

    serialized state • Converts url into state
  6. 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
  7. 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 });
  8. Back to the Router Router.map(function() { this.resource(‘search’); }); • map

    urls to routes • tells what objects to initialize for the url
  9. 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
  10. 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(); } });
  11. Rendered, now what? • Objects live in memory • Just

    sitting there • Until an event triggers an action
  12. 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
  13. 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’) });
  14. Computed Properties • functions that look like values • recalculates

    when read & invalidated • invalidated when dependent property changes
  15. 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
  16. 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
  17. 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’);
  18. 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
  19. 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
  20. 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’) }); }
  21. 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 });
  22. Anonymous functions in Stacktrace • Most lines you won’t recognize

    • 99% of problems are in your code • Name your functions so you recognize them
  23. 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’) });
  24. Isolate the problem 1. Identify simples model of the problem

    2. Create emberjs.jsbin.com 3. Ask on Stackoverflow or discuss.emberjs.com
  25. Make friends • Fastest way to learn is from others

    • Attend Hacker Hours • Help each other