| Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente |
| richclient:emberjs:components [2018/01/26 02:57] – [Passage de paramètres à un composant] jcheron | richclient:emberjs:components [2019/08/31 14:21] (Version actuelle) – modification externe 127.0.0.1 |
|---|
| <sxh html;title:app/templates/index.hbs> | <sxh html;title:app/templates/index.hbs> |
| {{#each model as |post|}} | {{#each model as |post|}} |
| {{blog-post title=post.title}} | {{#blog-post title=post.title}} |
| {{post.body}} | {{post.body}} |
| {{/blog-post}} | {{/blog-post}} |
| <div class="body">{{yield}}</div> | <div class="body">{{yield}}</div> |
| </sxh> | </sxh> |
| | |
| | |
| | ===== Personnalisation des éléments HTML ===== |
| | |
| | ==== Balise principale ==== |
| | |
| | Par défaut le code HTML généré par un composant l'est dans une **div**. |
| | <sxh html;gutter:false> |
| | <div id="ember180" class="ember-view"> |
| | <h1>My Component</h1> |
| | </div> |
| | </sxh> |
| | |
| | Il suffit de modifier la propriété **tagName** du composant dans la classe dérivée associée pour modifier cette balise par défaut : |
| | <sxh javascript;title:app/components/navigation-bar.js> |
| | import Component from '@ember/component'; |
| | |
| | export default Component.extend({ |
| | tagName: 'nav' |
| | }); |
| | </sxh> |
| | |
| | <sxh html;title:app/templates/components/navigation-bar.hbs> |
| | <ul> |
| | <li>{{#link-to "home"}}Home{{/link-to}}</li> |
| | <li>{{#link-to "about"}}About{{/link-to}}</li> |
| | </ul> |
| | </sxh> |
| | |
| | ==== Personnalisation de la classe css ==== |
| | |
| | La classe appliquée au composant qui sera généré peut être définie à son invocation, en tant qu'attribut html : |
| | |
| | <sxh html> |
| | {{navigation-bar class="primary"}} |
| | </sxh> |
| | |
| | Il est également possible de déterminer quelle classe css sera appliquée à un composant en affectant à sa propriété **classNames** un tableau de strings. |
| | |
| | <sxh javascript> |
| | import Component from '@ember/component'; |
| | |
| | export default Component.extend({ |
| | classNames: ['primary'] |
| | }); |
| | </sxh> |
| | |
| | Il est également possible de déterminer la classe css à partir des propriétés du composant en utilisant **classNameBindings**. |
| | |
| | Si une propriété booléenne est utilisée, la classe sera présente ou absente en fonction de la valeur de la propriété (false ou true) : |
| | |
| | |
| | <sxh javascript> |
| | import Component from '@ember/component'; |
| | |
| | export default Component.extend({ |
| | classNameBindings: ['isUrgent'], |
| | isUrgent: true |
| | }); |
| | </sxh> |
| | |
| | **classNameBindings** peut également porter une condition (si/alors/sinon) sur la valeur d'une propriété booléenne : |
| | <sxh javascript> |
| | import Component from '@ember/component'; |
| | |
| | export default Component.extend({ |
| | classNameBindings: ['isEnabled:enabled:disabled'], |
| | isEnabled: false |
| | }); |
| | </sxh> |
| | |
| | ==== Personnalisation des attributs HTML ==== |
| | |
| | La propriété **attributeBindings** permet de définir les attributs du DOM associés au HTML généré : |
| | <sxh javascript> |
| | import Component from '@ember/component'; |
| | |
| | export default Component.extend({ |
| | tagName: 'a', |
| | attributeBindings: ['href'], |
| | |
| | href: 'http://emberjs.com' |
| | }); |
| | </sxh> |
| | |
| | Il est possible de définir **attributeBindings** à partir d'une propriété du composant : |
| | <sxh javascript> |
| | import Component from '@ember/component'; |
| | |
| | export default Component.extend({ |
| | tagName: 'a', |
| | attributeBindings: ['customHref:href'], |
| | |
| | customHref: 'http://emberjs.com' |
| | }); |
| | </sxh> |
| | |
| | ===== Gestion des événements ===== |
| | |
| | |
| | <sxh html;title:app/templates/components/double-clickable.hbs> |
| | {{#double-clickable}} |
| | This is a double clickable area! |
| | {{/double-clickable}} |
| | </sxh> |
| | |
| | |
| | Ajout de la prise en charge de l'événement double click avec le hook **doubleClick** : |
| | <sxh javascript;title:app/components/double-clickable.js> |
| | import Component from '@ember/component'; |
| | |
| | export default Component.extend({ |
| | doubleClick() { |
| | alert("DoubleClickableComponent was clicked!"); |
| | } |
| | }); |
| | </sxh> |
| | |
| | |
| | Pour autoriser la propagation de l'événement sur les parents DOM du composant, la méthode évènementielle peut retourner **true**. |
| | <sxh javascript;title:app/components/double-clickable.js> |
| | import Component from '@ember/component'; |
| | |
| | export default Component.extend({ |
| | doubleClick() { |
| | alert("DoubleClickableComponent was clicked!"); |
| | return true; |
| | } |
| | }); |
| | </sxh> |
| | |
| | Voir la liste des [[https://guides.emberjs.com/v2.18.0/components/handling-events/#toc_event-names|events hook]] possibles |
| | |
| | ===== Actions ===== |
| | |
| | Création d'un composant appelant l'action définie dans la route active : |
| | |
| | Générer le composant : |
| | |
| | <sxh bash;gutter:false> |
| | ember generate component action-button |
| | </sxh> |
| | |
| | |
| | Implémenter le template du composant **action-button** : |
| | |
| | <sxh html;title:app/templates/components/action-button.hbs> |
| | <button {{action "doButtonThing"}} class="btn btn-default">{{yield}}</button> |
| | </sxh> |
| | |
| | Le template invoque l'action **doButtonThing** du composant qu'il va falloir créer dans le fichier **action-button.js** : |
| | |
| | <sxh javascript;title:app/components/action-button.js> |
| | import Ember from 'ember'; |
| | |
| | export default Ember.Component.extend({ |
| | actions: { |
| | doButtonThing() { |
| | this.sendAction('actionToCall'); |
| | } |
| | } |
| | }); |
| | </sxh> |
| | |
| | |
| | Le composant peut maintenant être utilisé dans une route /test : |
| | |
| | <sxh html;title:app/templates/test.hbs> |
| | {{#action-button actionToCall="continue"}}Continuer vers test/new{{/action-button}} |
| | </sxh> |
| | |
| | |
| | l'attribut **actionToCall** fait référence à l'action **continue** qu'il nous faut maintenant ajouter dans le route handler : |
| | |
| | <sxh javascript;title:app/routes/test.js> |
| | import Route from '@ember/routing/route'; |
| | |
| | export default Route.extend({ |
| | actions: { |
| | continue() { |
| | console.log("continuing on test/new page"); |
| | this.replaceWith('test.new'); |
| | } |
| | } |
| | }); |
| | </sxh> |
| | |
| | |
| | |