Ember: How the Concepts Scale Up

428167a3ec72235ba971162924492609?s=47 Yehuda Katz
February 18, 2014

Ember: How the Concepts Scale Up

428167a3ec72235ba971162924492609?s=128

Yehuda Katz

February 18, 2014
Tweet

Transcript

  1. 3.
  2. 4.
  3. 5.
  4. 6.
  5. 7.
  6. 8.
  7. 9.
  8. 10.
  9. 11.
  10. 12.
  11. 13.
  12. 14.
  13. 18.

    application.handlebars app.handlebars http://skylight.io/app/direwolf appkit/routes/app.js   export  default  Ember.Route.extend({
    model:

     function(params)  {
        return  this.store.find('app',
            params.app_id);
    }
 });
  14. 23.

    Ember Routing • Coming in from the URL should have

    the same code path as navigating around the application after the model is loaded.
  15. 24.

    Nested App.Router.map(function()  {
    this.resource('app',  {  path:  ':app_id'  },  function()

     {
        this.resource('endpoint',  {  path:  ':endpoint_id'  );
    });
 });
  16. 25.

    application.handlebars app.handlebars http://skylight.io/app/direwolf appkit/routes/app.js   export  default  Ember.Route.extend({
    model:

     function(params)  {
        return  this.store.find('app',
            params.app_id);
    }
 });   appkit/routes/app/index.js   export  default  Ember.Route.extend({
    model:  function()  {
        return  this.modelFor('app')
            .get('endpoints');
  }
 }); app/index.handlebars 
 !  {{#each}}
      {{link-­‐to  title  this}}
  {{/each}}
  17. 26.

    application.handlebars app.handlebars http://skylight.io/app/direwolf/Agent%23status appkit/routes/app.js   export  default  Ember.Route.extend({
    model:

     function(params)  {
        return  this.store.find('app',
            params.app_id);
    }
 });   appkit/routes/endpoint.js   export  default  Ember.Route.extend({
    model:  function(params)  {
      return  this.store.find('app',
            params.endpoint_id);
 }
 }); endpoint.handlebars
  18. 27.

    application.handlebars app.handlebars http://skylight.io/app/direwolf/Agent%23status appkit/routes/app.js   export  default  Ember.Route.extend({
    model:

     function(params)  {
        return  this.store.find('app',
            params.app_id);
    }
 });   appkit/routes/endpoint.js   export  default  Ember.Route.extend({
    model:  function(params)  {
      return  this.store.find('app',
            params.endpoint_id);
 }
 }); endpoint.handlebars nav.handlebars
  19. 28.

    Ember Routing • Coming in from the URL should have

    the same code path as navigating around the application after the model is loaded. • There is a single, consistent place to put setup and teardown logic for each page on the screen. • Nesting is built-in. Virtually every application has nesting, and your Week 1 code should serve you well in Week 2.
  20. 30.

    Setup Flow export  default  Ember.Route.extend({      renderTemplate:  function()  {

             this.render('nav',  {  outlet:  'nav'  });      },   !    redirect:  function()  {          var  user  =  this.modelFor('application'),                  apps  =  user.get('apps');   !        if  (!apps  ||  apps.get('length')  <  1)  {              this.replaceWith('setup');          }      }
 });
  21. 31.

    Ember Routing • Coming in from the URL should have

    the same code path as navigating around the application after the model is loaded. • There is a single, consistent place to put setup and teardown logic for each page on the screen. Think keyboard shortcuts. • Nesting is built-in. Virtually every application has nesting, and your Week 1 code should serve you well in Week 2.
  22. 33.

    Components ~ HTML Functions {{time-­‐explorer  rightMargin=152
        

                           brushExtent=dateRange
                                      endpoint=model
                                  timeRanges=timeRanges    
                    selectedTimeRange=selectedTimeRange}}  
  23. 34.

    Component Implementation <svg>      <defs>        

     <pattern  id="explorer-­‐grabber-­‐pattern"  width="1"  height="1">              <rect  class="border"  width="11"  height="22"></rect><rect  class="background"  x="1"  y="1"  width="9"  height="20"  rx="2"  ry="2"></rect>
            <rect  class="line"  x="3"  y="3"  width="1"  height="16"></rect><rect  class="line"  x="5"  y="3"  width="1"  height="16"></rect>
            <rect  class="line"  x="7"  y="3"  width="1"  height="16"></rect>          </pattern>          <linearGradient  id="left-­‐fade-­‐gradient"  x1="0"  x2="100%"  y1="0"  y2="0">              <stop  class="start"  offset="0%"></stop><stop  class="end"  offset="100%"></stop>          </linearGradient>          <linearGradient  id="right-­‐fade-­‐gradient"  x1="0"  x2="100%"  y1="0"  y2="0">              <stop  class="start"  offset="0%"></stop><stop  class="end"  offset="100%"></stop>          </linearGradient>          <linearGradient  id="brush-­‐background-­‐gradient"  x1="0"  x2="100%"  y1="0"  y2="0">              <stop  class="start"  offset="85%"></stop><stop  class="end"  offset="100%"></stop>          </linearGradient>      </defs>   </svg>   ! <div  class="controls">      <a  class="control  zoom-­‐in"  {{bind-­‐attr  class="canZoomIn:active"}}  title="Zoom  in">+</a>      <a  class="control  zoom-­‐out"  {{bind-­‐attr  class="canZoomOut:active"}}  title="Zoom  out">-­‐</a>      {{select-­‐popup  options=timeRanges  class="control"  value=selectedTimeRange}}   </div>
  24. 39.
  25. 40.

    Empty Help us keep the lights on. Enter your credit

    card information below, and we'll continue helping you make your Rails app the fastest it can be. Credit Card Card Number MM / YY CVC Save Credit Card We stole this graphic from GitHub for the wireframes; don't use in production! Credit Card Invalid This red glow is a placeholder until the final design is completed in Photoshop. Help us keep the lights on. Enter your credit card information below, and we'll continue helping you make your Rails app the fastest it can be. Credit Card 9999 9999 9999 9999 06 / 09 123 Save Credit Card The credit card you entered was invalid. When we can detect invalid information on the client (such as the Luhn checksum or expiry dates in the past), we should highlight the invalid field and display the error to the right of the Save button. Incomplete The Save button is dimmed until the entire form is filled out. Help us keep the lights on. Enter your credit card information below, and we'll continue helping you make your Rails app the fastest it can be. Credit Card MM / YY CVC Save Credit Card 4242 4242 4242 4242 Only one error should be displayed at a time. If there is more than one error, just show the first. {{billing-credit-card-form}} Component States Saved Clicking transitions to the Update Credit Card state. Update Thank you for being a Skylight customer. Credit Card Card Number MM / YY CVC Update Credit Card Cancel 4••• •••• •••• 4242 Expires 04/15 Update Credit Card Thank you for being a Skylight customer. Credit Card Saving Help us keep the lights on. Enter your credit card information below, and we'll continue helping you make your Rails app the fastest it can be. Credit Card 4242 4242 4242 4242 06 / 17 123 Saving… Error Saving Help us keep the lights on. Enter your credit card information below, and we'll continue helping you make your Rails app the fastest it can be. Credit Card 9999 9999 9999 9999 06 / 09 123 Save Credit Card The CVC you provided was incorrect. Because the server must validate any changes, the red glow should be removed and Save button enabled as soon as any changes to the field occur.
  26. 43.

    Feature Flag JS export  default  Ember.Component.extend({      flag:  null,

         inverse:  false,   !    init:  function()  {          this._super();          var  flag  =  this.get('flag');   !        Ember.defineProperty(this,  'featureEnabled',  Ember.computed(function()  {              var  value  =  this.get('config.flags.'+flag);              if  (this.get('inverse'))  {  value  =  !value;  }              return  value;          }).property('config.flags.'+flag,  'inverse'));      }   });
  27. 45.

    config/initializers/config.js.es6 /*      This  initializer  injections  global  configuration  options

     onto  object  instances,  so  they  do  not
    need  to  rely  on  accessing  globals.   !    Currently  all  of  the  config  options  are  defined  in  config/environment.js,  but  this  may  change  over  time.   !    To  access  a  config  option  on,  e.g.,  a  model,  do:   !        this.config.flags.keyRequests;  //=>  false          this.config.defaultRanges  =  [  {  },  {  },  ...  ];   */   export  default  {      name:  "config",      initialize:  function(container,  application)  {          container.register('config:main',  Ember.Object.extend(CONF));   !        ['model',  'view',  'controller',  'route',  'component'].forEach(function(type)  {              container.injection(type,  'config',  'config:main');          });      }   };
  28. 46.

    environment.js var  FEATURE_FLAGS  =  {      keyRequests:  false,  

       appDashboard:  false   };   ! window.CONF  =  {    zeroClipboard:  {          moviePath:  "/assets/zeroclipboard/ZeroClipboard.swf",          trustedDomains:  ['*'],          allowScriptAccess:  "always"      },      trialDays:  30,      flags:  FEATURE_FLAGS,      defaultTimeRanges:  [          {  name:  'Last  6  hours',  timestamp:  'recent',  duration:  21600  },          {  name:  'Last  30  minutes',  timestamp:  'recent',  duration:  1800  },          {  name:  'Last  5  minutes',  timestamp:  'recent',  duration:  300  }      ]   };
  29. 48.

    ES6 Module import  $  from  'jquery';
 import  {  config  }

     from  'app/config';
 
 var  viewA  =  Ember.Object.extend({
    //  ...
 });
 
 var  viewB  =  Ember.Object.extend({
    //  ...
 });
 
 export  viewA;
 export  viewB; define(['jquery',  'app/config',  'exports'],
    function($,  appConfig,  exports)  {
        var  config  =  appConfig.config;
 
        var  viewA  =  Ember.Object.extend({
            //  ...
        });
 
        var  viewB  =  Ember.Object.extend({
            //  ...
        });
 
        exports.viewA  =  viewA;
        exports.viewB  =  viewB;
    }); AMD Module
  30. 49.

    Improvements • Cyclic Dependencies • Named and Default exports together

    (including cycles!) • Much, much prettier syntax, with familiar semantics • Why not?
  31. 50.

    ES6 Module Transpiler • Maintained by Square • Supports almost

    all of ES6 modules • Emits AMD-, Node- or Globals-based output • Compatibility with existing AMD and Node modules (including default exports) • Ships out of the box with Ember App Kit