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

EmberJS Amsterdam - Closure Actions

Marten
March 10, 2016

EmberJS Amsterdam - Closure Actions

Marten

March 10, 2016
Tweet

More Decks by Marten

Other Decks in Programming

Transcript

  1. actions: {
 saveModel() {
 // saves model
 },
 
 submit()

    {
 this.send(‘saveModel’);
 }
 } CALLING ACTIONS FROM YOUR COMPONENT
  2. actions: {
 saveModel() {
 // saves model
 },
 
 submit()

    {
 this.send(‘saveModel’);
 }
 } CALLING ACTIONS FROM YOUR COMPONENT
  3. // controllers/login.js
 actions: {
 login(username, password) {
 // logic
 }


    } {{! templates/login.hbs }}
 {{login-form login=“login”}} LOGIN
  4. // components/login-form.js
 actions: {
 submit() {
 this.sendAction(‘login’,
 get(this, ‘username’),
 get(this,

    ‘password’));
 }
 } {{! templates/components/login-form.hbs }}
 {{#x-button action=“submit”}}
 Login
 {{/x-button}} COMPONENTS/LOGIN-FORM
  5. // components/x-button.js
 actions: {
 click() {
 this.sendAction();
 }
 } {{!

    templates/components/x-button.hbs }}
 <button {{action “click”}}>
 {{yield}}
 </button> COMPONENTS/X-BUTTON
  6. // components/x-button.js
 actions: {
 click() {
 this.sendAction();
 }
 } {{!

    templates/components/x-button.hbs }}
 <button {{action “click”}}>
 {{yield}}
 </button> COMPONENTS/X-BUTTON
  7. // components/x-button.js
 actions: {
 click() {
 this.sendAction();
 }
 } {{!

    templates/components/x-button.hbs }}
 <button {{action “click”}}>
 {{yield}}
 </button> COMPONENTS/X-BUTTON
  8. // components/x-button.js
 actions: {
 click() {
 this.sendAction();
 }
 } {{!

    templates/components/x-button.hbs }}
 <button {{action “click”}}>
 {{yield}}
 </button> COMPONENTS/X-BUTTON
  9. // components/login-form.js
 actions: {
 submit() {
 this.sendAction(‘login’,
 get(this, ‘username’),
 get(this,

    ‘password’));
 }
 } {{! templates/components/login-form.hbs }}
 {{#x-button action=“submit”}}
 Login
 {{/x-button}} COMPONENTS/LOGIN-FORM
  10. // components/login-form.js
 actions: {
 submit() {
 this.sendAction(‘login’,
 get(this, ‘username’),
 get(this,

    ‘password’));
 }
 } {{! templates/components/login-form.hbs }}
 {{#x-button action=“submit”}}
 Login
 {{/x-button}} COMPONENTS/LOGIN-FORM
  11. // components/login-form.js
 actions: {
 submit() {
 this.sendAction(‘login’,
 get(this, ‘username’),
 get(this,

    ‘password’));
 }
 } {{! templates/components/login-form.hbs }}
 {{#x-button action=“submit”}}
 Login
 {{/x-button}} COMPONENTS/LOGIN-FORM
  12. // controllers/login.js
 actions: {
 login(username, password) {
 // logic
 }


    } {{! templates/login.hbs }}
 {{login-form login=“login”}} LOGIN
  13. // controllers/login.js
 actions: {
 login(username, password) {
 // logic
 }


    } {{! templates/login.hbs }}
 {{login-form login=“login”}} LOGIN
  14. {{! templates/components/login-form.hbs }}
 {{#if user}}
 You have been successfully logged

    in as: 
 {{user.username}}
 {{else}}
 {{input value=username}}
 {{input value=password}}
 
 <button {{action “submit”}}>Login</button>
 {{/if}} COMPONENTS/LOGIN-FORM
  15. {{! templates/components/login-form.hbs }}
 {{#if user}}
 You have been successfully logged

    in as: 
 {{user.username}}
 {{else}}
 {{input value=username}}
 {{input value=password}}
 
 <button {{action “submit”}}>Login</button>
 {{/if}} COMPONENTS/LOGIN-FORM
  16. // components/login-form.js
 actions: {
 submit() {
 let setUser = user

    => set(this, ‘user’, user);
 this.sendAction(‘login’, 
 get(this, ‘username’),
 get(this, ‘password’),
 setUser);
 }
 } COMPONENTS/LOGIN-FORM
  17. // components/login-form.js
 actions: {
 submit() {
 let setUser = user

    => set(this, ‘user’, user);
 this.sendAction(‘login’, 
 get(this, ‘username’),
 get(this, ‘password’),
 setUser);
 }
 } COMPONENTS/LOGIN-FORM
  18. // controllers/login.js
 actions: {
 login(username, password, setUser) {
 let user

    = this._login(username, password); setUser(user);
 }
 } {{! templates/login.hbs }}
 {{login-form login=“login”}} LOGIN
  19. // controllers/login.js
 actions: {
 login(username, password, setUser) {
 let user

    = this._login(username, password); setUser(user);
 }
 } {{! templates/login.hbs }}
 {{login-form action=“login”}} LOGIN
  20. // controllers/login.js
 actions: {
 login(username, password, setUser) {
 let user

    = this._login(username, password); setUser(user);
 }
 } {{! templates/login.hbs }}
 {{login-form action=“login”}} LOGIN
  21. {{! templates/components/login-form.hbs }}
 {{#if user}}
 You have been successfully logged

    in as: 
 {{user.username}}
 {{else}}
 {{input value=username}}
 {{input value=password}}
 
 <button {{action “submit”}}>Login</button>
 {{/if}} COMPONENTS/LOGIN-FORM
  22. {{! templates/components/login-form.hbs }}
 {{#if user}}
 You have been successfully logged

    in as: 
 {{user.username}}
 {{else}}
 {{input value=username}}
 {{input value=password}}
 
 <button {{action “submit”}}>Login</button>
 {{/if}} COMPONENTS/LOGIN-FORM
  23. // components/login-form.js
 actions: {
 submit() {
 let setUser = user

    => set(this, ‘user’, user);
 this.sendAction(‘login’, 
 get(this, ‘username’),
 get(this, ‘password’),
 setUser);
 }
 } COMPONENTS/LOGIN-FORM
  24. // components/login-form.js
 actions: {
 submit() {
 let setUser = user

    => set(this, ‘user’, user);
 this.sendAction(‘login’, 
 get(this, ‘username’),
 get(this, ‘password’),
 setUser);
 }
 } COMPONENTS/LOGIN-FORM
  25. // components/login-form.js
 actions: {
 submit() {
 let setUser = user

    => set(this, ‘user’, user);
 this.sendAction(‘login’, 
 get(this, ‘username’),
 get(this, ‘password’),
 setUser);
 }
 } COMPONENTS/LOGIN-FORM
  26. // controllers/login.js
 actions: {
 login(username, password, setUser) {
 let user

    = this._login(username, password); setUser(user);
 }
 } {{! templates/login.hbs }}
 {{login-form login=“login”}} LOGIN
  27. // controllers/login.js
 actions: {
 login(username, password, setUser) {
 let user

    = this._login(username, password); setUser(user);
 }
 } {{! templates/login.hbs }}
 {{login-form login=“login”}} LOGIN
  28. // controllers/login.js
 actions: {
 login(username, password, setUser) {
 let user

    = this._login(username, password); setUser(user);
 }
 } {{! templates/login.hbs }}
 {{login-form login=“login”}} LOGIN
  29. // controllers/login.js
 actions: {
 login(username, password, setUser) {
 let user

    = this._login(username, password); setUser(user);
 }
 } {{! templates/login.hbs }}
 {{login-form login=“login”}} LOGIN
  30. // controllers/login.js
 actions: {
 login(username, password, setUser) {
 let user

    = this._login(username, password); setUser(user);
 }
 } {{! templates/login.hbs }}
 {{login-form login=“login”}} LOGIN
  31. // components/login-form.js
 actions: {
 submit() {
 let setUser = user

    => set(this, ‘user’, user);
 this.sendAction(‘login’, 
 get(this, ‘username’),
 get(this, ‘password’),
 setUser);
 }
 } COMPONENTS/LOGIN-FORM
  32. // components/login-form.js
 actions: {
 submit() {
 let setUser = user

    => set(this, ‘user’, user);
 this.sendAction(‘login’, 
 get(this, ‘username’),
 get(this, ‘password’),
 setUser);
 }
 } COMPONENTS/LOGIN-FORM
  33. {{! templates/components/login-form.hbs }}
 {{#if user}}
 You have been successfully logged

    in as: 
 {{user.username}}
 {{else}}
 {{input value=username}}
 {{input value=password}}
 
 {{#x-button action=“submit”}}
 Login
 {{/x-button}}
 {{/if}} COMPONENTS/LOGIN-FORM
  34. {{! templates/components/login-form.hbs }}
 {{#if user}}
 You have been successfully logged

    in as: 
 {{user.username}}
 {{else}}
 {{input value=username}}
 {{input value=password}}
 
 {{#x-button action=“submit”}}
 Login
 {{/x-button}}
 {{/if}} COMPONENTS/LOGIN-FORM
  35. {{! before}}
 <button {{action “submit”}}>
 Submit
 </button> {{! with closure

    actions}}
 <button onclick={{action “submit”}}>
 Submit
 </button> BINDING ACTIONS TO HTML ELEMENTS
  36. {{! before}}
 <form {{action “submit” on=“submit”}}>
 <!—— form fields ——>


    </form> {{! with closure actions}}
 <form onsubmit={{action “submit”}}>
 <!—— form fields ——>
 </form> BINDING ACTIONS TO HTML ELEMENTS
  37. {{! before}}
 {{#x-button action=“submit”}}
 Submit
 {{/x-button}} {{! with closure actions}}


    {{#x-button click=(action “submit”)}}
 Submit
 {{/x-button}} BINDING ACTIONS TO COMPONENTS
  38. {{#x-button click=(action “submit”)}}
 Submit
 {{/x-button}} BINDING ACTIONS TO COMPONENTS {{#x-button

    click=(action submit)}}
 Submit
 {{/x-button}} action called from actions hash
  39. {{#x-button click=(action “submit”)}}
 Submit
 {{/x-button}} BINDING ACTIONS TO COMPONENTS {{#x-button

    click=(action submit)}}
 Submit
 {{/x-button}} action called from component attributes
  40. // before
 actions: {
 submit() {
 this.sendAction(‘submit’);
 }
 } //

    with closure actions
 actions: {
 submit() {
 get(this, ‘submit’)();
 }
 } CALLING ACTIONS FROM YOUR COMPONENT
  41. // controllers/items.js
 actions: {
 saveItem(item) {
 item.save();
 }
 } ITEMS

    {{! templates/items.hbs
 {{item-list saveItem=(action “saveItem”)}}
  42. // controllers/items.js
 actions: {
 saveItem(item) {
 item.save();
 }
 } ITEMS

    {{! templates/items.hbs
 {{item-list saveItem=(action “saveItem”)}}
  43. // controllers/items.js
 actions: {
 saveItem(item) {
 item.save();
 }
 } ITEMS

    {{! templates/items.hbs
 {{item-list saveItem=(action “saveItem”)}}
  44. {{item-list itemAction=(action “doAction”)}} {{item-detail itemAction=(action itemAction item)}} <button onclick={{action itemAction

    “save”}}>
 <button onclick={{action itemAction “destroy”}}> items components/item-list components/item-detail CURRYING
  45. {{item-list itemAction=(action “doAction”)}} {{item-detail itemAction=(action itemAction item)}} <button onclick={{action itemAction

    “save”}}>
 <button onclick={{action itemAction “destroy”}}> items components/item-list components/item-detail CURRYING
  46. // controllers/items.js
 actions: {
 doAction(item, action) {
 item[action]();
 }
 }

    ITEMS {{! templates/items.hbs
 {{item-list itemAction=(action “doAction”)}}
  47. // controllers/items.js
 actions: {
 doAction(item, action) {
 item[action]();
 }
 }

    ITEMS {{! templates/items.hbs
 {{item-list itemAction=(action “doAction”)}}
  48. // controllers/items.js
 actions: {
 doAction(item, action) {
 item[action]();
 }
 }

    ITEMS {{! templates/items.hbs
 {{item-list itemAction=(action “doAction”)}}
  49. // controllers/items.js
 actions: {
 doAction(item, action) {
 item[action]();
 }
 }

    ITEMS {{! templates/items.hbs
 {{item-list itemAction=(action “doAction”)}}
  50. {{item-list itemAction=(action “doAction”)}} {{item-detail itemAction=(action itemAction item)}} <button onclick={{action itemAction

    “save”}}>
 <button onclick={{action itemAction “destroy”}}> items components/item-list components/item-detail CURRYING
  51. {{item-list itemAction=(action “doAction”)}} {{item-detail itemAction=(action itemAction item)}} <button onclick={{action itemAction

    “save”}}>
 <button onclick={{action itemAction “destroy”}}> items components/item-list components/item-detail CURRYING
  52. {{item-list itemAction=(action “doAction”)}} {{item-detail itemAction=(action itemAction item)}} <button onclick={{action itemAction

    “save”}}>
 <button onclick={{action itemAction “destroy”}}> items components/item-list components/item-detail CURRYING
  53. {{! templates/components/item-detail.hbs
 <button onclick={{action itemAction “save”}}>
 Save
 </button> CURRYING {{!

    templates/components/item-list.hbs
 {{#each items as |item|}}
 {{item-detail
 item=item
 itemAction=(action itemAction item)}}
 {{/each}}
  54. {{! templates/components/item-detail.hbs
 <button onclick={{action itemAction “save”}}>
 Save
 </button> CURRYING {{!

    templates/components/item-list.hbs
 {{#each items as |item|}}
 {{item-detail
 item=item
 itemAction=(action itemAction item)}}
 {{/each}} {{action itemAction item “save”}}
  55. {{! templates/components/item-detail.hbs
 <button onclick={{action itemAction “destroy”}}>
 Destroy
 </button> CURRYING {{!

    templates/components/item-list.hbs
 {{#each items as |item|}}
 {{item-detail
 item=item
 itemAction=(action itemAction item)}}
 {{/each}} {{action itemAction item “destroy”}}
  56. {{item-list itemAction=(action “doAction”)}} {{item-detail itemAction=(action itemAction item)}} <button onclick={{action itemAction

    “save”}}>
 <button onclick={{action itemAction “destroy”}}> items components/item-list components/item-detail CURRYING
  57. {{! templates/components/item-detail.hbs
 <button onclick={{action itemAction “save”}}>
 Save
 </button> CURRYING //

    controllers/items.js
 actions: {
 doAction(item, action) {
 item[action]();
 }
 } {{action itemAction item “save”}}
  58. {{! templates/components/item-detail.hbs
 <button onclick={{action itemAction “save”}}>
 Save
 </button> CURRYING //

    controllers/items.js
 actions: {
 doAction(item, action) {
 item[action](); // item.save();
 }
 } {{action itemAction item “save”}}
  59. {{! templates/components/item-detail.hbs
 <button onclick={{action itemAction “destroy”}}>
 Save
 </button> CURRYING //

    controllers/items.js
 actions: {
 doAction(item, action) {
 item[action]();
 }
 } {{action itemAction item “destroy”}}
  60. {{! templates/components/item-detail.hbs
 <button onclick={{action itemAction “destroy”}}>
 Save
 </button> CURRYING //

    controllers/items.js
 actions: {
 doAction(item, action) {
 item[action](); // item.destroy();
 }
 } {{action itemAction item “destroy”}}
  61. // controllers/login.js
 actions: {
 login(username, password, setUser) {
 let user

    = this._login(username, password); setUser(user);
 }
 } {{! templates/login.hbs }} {{login-form login=“login”}} LOGIN
  62. // controllers/login.js
 actions: {
 login(username, password, setUser) {
 let user

    = this._login(username, password); setUser(user);
 }
 } {{! templates/login.hbs }} {{login-form login=“login”}} LOGIN
  63. // controllers/login.js
 actions: {
 login(username, password) {
 return this._login(username, password);


    }
 } {{! templates/login.hbs }} {{login-form login=(action “login”)}} LOGIN
  64. {{! templates/components/login-form.hbs }}
 {{#if user}}
 You have been successfully logged

    in as: 
 {{user.username}}
 {{else}}
 {{input value=username}}
 {{input value=password}}
 
 <button {{action “submit”}}>Login</button>
 {{/if}} COMPONENTS/LOGIN-FORM
  65. {{! templates/components/login-form.hbs }}
 {{#if user}}
 You have been successfully logged

    in as: 
 {{user.username}}
 {{else}}
 {{input value=username}}
 {{input value=password}}
 
 <button {{action “submit”}}>Login</button>
 {{/if}} COMPONENTS/LOGIN-FORM
  66. {{! templates/components/login-form.hbs }}
 {{#if user}}
 You have been successfully logged

    in as: 
 {{user.username}}
 {{else}}
 {{input value=username}}
 {{input value=password}}
 
 <button onclick={{action “submit”}}>
 Login
 </button>
 {{/if}} COMPONENTS/LOGIN-FORM
  67. // components/login-form.js
 actions: {
 submit() {
 let setUser = user

    => set(this, ‘user’, user);
 this.sendAction(‘login’, 
 get(this, ‘username’),
 get(this, ‘password’),
 setUser);
 }
 } COMPONENTS/LOGIN-FORM
  68. // components/login-form.js
 actions: {
 submit() {
 let user = get(this,

    ‘login’)( 
 get(this, ‘username’),
 get(this, ‘password’)
 );
 set(this, ‘user’, user);
 }
 } COMPONENTS/LOGIN-FORM
  69. {{! templates/components/login-form.hbs }}
 {{#if user}}
 You have been successfully logged

    in as: 
 {{user.username}}
 {{else}}
 {{input value=username}}
 {{input value=password}}
 
 <button onclick={{action “submit”}}>
 Login
 </button>
 {{/if}} COMPONENTS/LOGIN-FORM
  70. // components/login-form.js
 actions: {
 submit() {
 let user = get(this,

    ‘login’)( 
 get(this, ‘username’),
 get(this, ‘password’)
 );
 set(this, ‘user’, user);
 }
 } COMPONENTS/LOGIN-FORM
  71. // components/login-form.js
 actions: {
 submit() {
 let user = get(this,

    ‘login’)( 
 get(this, ‘username’),
 get(this, ‘password’)
 );
 set(this, ‘user’, user);
 }
 } COMPONENTS/LOGIN-FORM
  72. // controllers/login.js
 actions: {
 login(username, password) {
 return this._login(username, password);


    }
 } {{! templates/login.hbs }} {{login-form login=(action “login”)}} LOGIN
  73. // controllers/login.js
 actions: {
 login(username, password) {
 return this._login(username, password);


    }
 } {{! templates/login.hbs }} {{login-form login=(action “login”)}} LOGIN
  74. // controllers/login.js
 actions: {
 login(username, password) {
 return this._login(username, password);


    }
 } {{! templates/login.hbs }} {{login-form login=(action “login”)}} LOGIN
  75. // components/login-form.js
 actions: {
 submit() {
 let user = get(this,

    ‘login’)( 
 get(this, ‘username’),
 get(this, ‘password’)
 );
 set(this, ‘user’, user);
 }
 } COMPONENTS/LOGIN-FORM
  76. // components/login-form.js
 actions: {
 submit() {
 let user = get(this,

    ‘login’)( 
 get(this, ‘username’),
 get(this, ‘password’)
 );
 set(this, ‘user’, user);
 }
 } COMPONENTS/LOGIN-FORM
  77. // components/login-form.js
 actions: {
 submit() {
 let user = get(this,

    ‘login’)( 
 get(this, ‘username’),
 get(this, ‘password’)
 );
 set(this, ‘user’, user);
 }
 } COMPONENTS/LOGIN-FORM
  78. {{! templates/components/login-form.hbs }}
 {{#if user}}
 You have been successfully logged

    in as: 
 {{user.username}}
 {{else}}
 {{input value=username}}
 {{input value=password}}
 
 <button onclick={{action “submit”}}>
 Login
 </button>
 {{/if}} COMPONENTS/LOGIN-FORM
  79. {{! templates/components/login-form.hbs }}
 {{#if user}}
 You have been successfully logged

    in as: 
 {{user.username}}
 {{else}}
 {{input value=username}}
 {{input value=password}}
 
 <button onclick={{action “submit”}}>
 Login
 </button>
 {{/if}} COMPONENTS/LOGIN-FORM
  80. <input oninput={{action “updateValue” 
 value=“target.value”}} />
 actions: {
 updateValue(event) {


    set(this, ‘value’, event.target.value);
 }
 } FIRST ARGUMENT VALUE gets value from given path on first argument
  81. FIRST ARGUMENT VALUE {{my-input 
 value=value
 updateValue=(action “updateValue”)
 }} actions:

    {
 updateValue(value) {
 set(this, ‘value’, value);
 }
 }
  82. // What will happen?
 actions: {
 alert() {
 alert(‘1337 HAXX0R’);


    }
 }
 
 {{my-component init=(action “alert”)}} OVERRIDING FUNCTIONS
  83. // This will happen!
 Assertion Failed: 
 You must call

    `this._super` when implementing `init` in a component. OVERRIDING FUNCTIONS
  84. <button {{action (pipe 
 addToCart 
 purchase 
 goToThankYouPage) 


    item}}
 >
 1-Click Buy
 </button> EMBER-COMPOSABLE-ACTIONS
  85. <button {{action (pipe 
 addToCart 
 purchase 
 goToThankYouPage) 


    item}}
 >
 1-Click Buy
 </button> EMBER-COMPOSABLE-ACTIONS
  86. <button {{action (pipe 
 addToCart 
 purchase 
 goToThankYouPage) 


    item}}
 >
 1-Click Buy
 </button> EMBER-COMPOSABLE-ACTIONS
  87. <button {{action (pipe 
 addToCart 
 purchase 
 goToThankYouPage) 


    item}}
 >
 1-Click Buy
 </button> EMBER-COMPOSABLE-ACTIONS
  88. <button {{action (pipe 
 addToCart 
 purchase 
 goToThankYouPage) 


    item}}
 >
 1-Click Buy
 </button> EMBER-COMPOSABLE-ACTIONS