Controllers & templates

Créer un controlleur

  1. Le controlleur contrôle ce qui est accessible dans le template. Il peut notamment définir des variables.
    app/controllers/application.js:

     import Controller from '@ember/controller';
    
     /**
      * Main controller of the application.
      *
      * @class ApplicationController
      * @extends Controller
      */
     export default class ApplicationController extends Controller {
       username = "Bob";
    
       get sayHello() {
         return `Hello ${this.username}`;
       }
     }
    
  2. Les propriétés du controlleur sont directement accessibles dans le template (ou via this)
    app/templates/application.hbs:

     <p>Hello {{username}}</p>
     <p>Hello {{this.username}}</p>
     <p>{{sayHello}}</p>
    

Écouter des événements

  1. Pour exécuter du code lorsqu’un événement est déclenché,
    créer une méthode avec le décorateur @action dans le controlleur
    app/controllers/application.js:

     import Controller from '@ember/controller';
     import { action } from '@ember/object';
    
     export default class ApplicationController extends Controller {
    
       @action
       handleClick(e) {
         console.log(e);
         alert('You clicked!');
       }
     }
    
  2. Et dans le template, utiliser le helper on pour ajouter un listener (avec tout type d’événement du DOM):
    app/templates/application.hbs:

     <button {{on "click" this.handleClick}}>Click me</button>
    

Méthode avec arguments

  1. Pour passer des arguments à une méthode,
    à la place d’utiliser la méthode directement comme callback, on utilise le helper fn:
    app/templates/application.hbs:

     <button {{on "click" (fn this.handleClick "A")}}>Click A</button>
     <button {{on "click" (fn this.handleClick "B")}}>Click B</button>
    
  2. Dans tous les cas, le controlleur reçoit toujours l’événement en dernier argument.
    app/controllers/application.js:

     import Controller from '@ember/controller';
     import { action } from '@ember/object';
    
     export default class ApplicationController extends Controller {
    
       @action
       handleClick(value, e) {
         console.log(e);
         alert(`You clicked ${value}!`);
       }
     }
    

Mettre à jour la vue

  1. Pour que la vue soit mise à jour quand une variable est modifiée,
    il faut ajouter le décorateur @tracked sur cette variable
    app/controllers/application.js:

     import Controller from '@ember/controller';
     import { action } from '@ember/object';
     import { tracked } from '@glimmer/tracking';
    
     export default class ApplicationController extends Controller {
       @tracked count = 0;
    
       @action
       handleClick() {
         this.count += 1;
       }
     }
    
  2. Dans le template, on utilise la variable comme d’habitude
    app/templates/application.hbs:

     <button {{on "click" this.handleClick}}>
       You clicked {{this.count}} times
     </button>
    

Helpers natifs

if

unless

each

each-in

concat

let

hash

array

get

prop

Combiner des helpers

Liste complète des helpers


Helper personnalisé

  1. Pour créer un helper personnalisé,
    définir un helper dans app/helpers.

    • Soit en utilisant une fonction

       import { helper } from '@ember/component/helper';
      
       export function percent(params, namedArgs={}) {
         ...
       }
       export default helper(percent);
      
    • Soit une classe

      import Helper from '@ember/component/helper';
      
      export default class percent extends Helper {
        compute(params, namedArgs={}) {
          ...
        }
      }
      

    Exemple:
    app/helpers/percent.js

     import { helper } from '@ember/component/helper';
    
     export function percent([value], namedArgs={}) {
       if(typeof value !== 'number') return;
    
       var suffix    = namedArgs.suffix ?? '%';
       var precision = namedArgs.precision ?? 2;
       var percent   = (value * 100).toFixed(precision);
    
       return `${percent}${suffix}`;
     }
     export default helper(percent);
    

    app/helpers.permission.js

     import Helper from '@ember/component/helper';
     import { inject as service } from '@ember/service';
     import permissions from 'dacapo-front/permissions/index';
    
     /**
      * Check permissions on given object.
      * Usage :
      *
      *     {{if (permission "patient.update" this.model) }}
      *     {{if (permission "studyMedical.create" patient=this.patient) }}
      *
      * @return Boolean
      */
     export default class PermissionHelper extends Helper {
       @service permission;
    
       compute([abilityString, model], properties = {}) {
         return this.permission.has(abilityString, model, properties);
       }
     }
    
  2. Appeler le helper dans le template

     {{percent 0.98946 precision=0}}