Présentation de EmberJS

Publié le 12 novembre 2013 par Alexandre Salaun | front

Cet article est publié sous licence CC BY-NC-SA

EmberJS est un framework javascript MVC, le code est disponible sur leur dépôt Github. D’un point de vue historique, EmberJS est issu de SproutCore ou plus précisément de SproutCore 2.

Ce framework s’utilise côté client, tout comme BackboneJS. Il permet de gérer les actions utilisateur sur une page sans rechargement et permet donc de créer des one-page-applications.

Les sites ou applications web utilisant ce genre de framework (Angular, Ember, Backbone…) disposent d’une API (créée avec le langage de votre choix, dans notre cas ce sera Ruby via le framework Ruby On Rails) afin de s’interfacer avec une base de données. EmberJS n’est pas déstiné à gérer l’accès à la base de données, il est là pour faciliter le rendu des pages et les interactions avec l’utilisateur.

La version 1.0 de ce framework est sortie le 31 août 2013, on peut donc considérer qu’il est suffisamment utilisé et testé pour nous y mettre nous aussi.

A travers une série d’articles, nous allons essayer de nous familiariser avec EmberJS. Nous irons progressivement vers des choses un peu plus complexes, cet article n’étant qu’une présentation du framework.

Pourquoi utiliser EmberJS ?

EmberJS a un intérêt lorsque l’on souhaite développer une application comportant une part de javascript assez conséquente. A l’heure actuelle, de plus en plus d’applications évitent les rechargements de pages au maximum afin de rendre plus fluide la navigation pour l’utilisateur.

Attention tout de même, ce n’est pas parce que vous utilisez EmberJS que tous vos soucis seront réglés. On peut très bien imaginer une application web utilisant EmberJS et qui, pour autant, n’est pas fluide du tout si l’on ne fait pas les choses correctement. Ce n’est pas forcément le temps rendu d’une page (après rechargement) qui est problématique. Cela peut également venir du temps de traitement des requêtes vers la base de données ou bien d’autres choses.

Il arrive fréquemment que l’on doive mettre à jour uniquement une partie de notre page après une action utilisateur, comme, par exemple, modifier le nom de l’utilisateur à tous les endroits où on le retrouve sur la page après une soumission de formulaire d’édition de profil. Pour ce genre de comportement, EmberJS propose des fonctionnalités qui vous seront très utiles comme nous le verrons par la suite.

Comme nous l’avons précisé plus tôt dans l’article, il vous faudra, la plupart du temps, utiliser une API afin de fournir des données à EmberJS. Utilisant Rails dans tous mes projets de développement je ne vais donc pas changer mes habitudes ici mais vous pouvez très bien utiliser EmberJS avec un autre langage.

De nombreuses ressources sont disponibles sur le net si vous souhaitez combiner EmberJS à un autre langage que Ruby.

EmberJS et Rails

Il est possible d’intégrer EmberJS dans une application Ruby On Rails grâce à la gem ember-rails. L’un des principaux cas d’utilisation va donc être de développer une API avec Rails et gérer l’interface avec EmberJS. C’est la combinaison de ces deux outils qui va nous intéresser principalement dans cette série d’articles.

Installation et configuration

Comme dis précédemment, une gem est disponible afin d’utiliser EmberJS dans une application Rails, il suffit donc, dans un premier temps, de l’ajouter au Gemfile de votre application (plusieurs gems sont nécessaires) :

gem 'ember-rails'
gem 'ember-source'

Lancez la commande bundle install afin de finaliser l’installation du framework javascript. Ensuite, une commande existe afin de créer le squelette et les fichiers nécessaires à l’utilisation d’EmberJS :

rails g ember:bootstrap

Si vous utilisez CoffeeScript (jetez un œil à notre présentation de coffeescript si ce n’est pas le cas), il est possible de le spécifier pour générer des fichiers .coffee plutôt que .js :

rails g ember:bootstrap --javascript-engine coffee

Vous pouvez constater qu’un certain nombre de fichiers et de répertoires ont été créés dans le répertoire app/assets de votre application Rails. Lorsque l’on observe la structure d’une application utilisant EmberJS on retrouve des éléments communs à tous les frameworks MVC : des modèles, des controllers, des fichiers de vue/templates… on n’est donc pas dépaysé par rapport à Rails.

Comme nous venons de le voir, il est possible de passer différentes options à la commande permettant de générer le squelette :

--ember-path         # spécifier le chemin d'ember (équivalent : -d)
--skip-git           # ne pas créer les fichiers .gitkeep (équivalent : -g)
--javascript-engine  # spécifier le langage (js ou coffee)
--app-name           # spcifier un nom d'application personnalisé  (équivalent : -n)

Il est possible de définir d’autres options pour Ember dans le fichier config/application.rb et même de différencier ces options suivant l’environnement dans lequel on se trouve en utilisant les fichiers correspondant à chacun des environnements (config/development.rb, config/staging.rb, config/production.rb…). Voici la liste des options disponibles :

config.ember.variant                        # spécifier un environnement à Ember (valeurs possibles : :development ou :production).
config.ember.app_name                       # spécifier le nom de l'application (il sera utilisé par les générateurs)
config.ember.ember_path                     # spécifier un chemin spécifique aux générateurs
config.handlebars.precompile                # activer/désactiver la pré-compilation (par défaut : true)
config.handlebars.templates_root            # spécifier le chemin du répertoire (dans app/assets/javascripts) où se trouveront les templates (par défaut : 'templates')
config.handlebars.templates_path_separator  # spécifier le séparateur pour les urls dans les templates (par défaut : '/')
config.handlebars.output_type               # spécifier le style des outputs (valeurs possibles : :global, :amd, par défaut : :global)

Si vous configurez comme valeur pour l’option variant :development alors vous pourrez constater que vous avez des debugger dans la console javascript de votre navigateur. Il existe par ailleurs un plugin pour Chrome afin d’obtenir un débogueur plus complet.

Afin de tester que votre application fonctionne correctement, vous pouvez ajouter un logger qui sera appelé après le chargement d’Ember :

# dans votre fichier app/assets/javascripts/application.js ou application.js.coffee
window.MyAppName = Ember.Application.create(
  ready: ->
    console.log 'Hello world !' # ou quelque chose de plus original si vous le souhaitez
)

Si ce message s’affiche dans la console alors vous avez une application configurée et prête pour l’utilisation d’EmberJS, nous allons voir ce qu’il est possible de faire. Si ce message ne s’affiche pas, vérifiez bien la configuration d’Ember et qu’il n’y a pas d’erreur dans votre manifest javascript.

Un exemple simple

Il n’y a rien de mieux, pour maîtriser un nouvel outil, que de s’en servir. Nous allons donc commencer par un cas d’utilisation très simple d’EmberJS.

Afin de pouvoir jouer un peu avec EmberJS nous allons créer une nouvelle application Rails avec uniquement un model (nommé ici Team). Après avoir ajouté une route et une vue (qui peut être vide) pour la homepage et les routes et le controller pour le model créé nous allons pouvoir commencer à nous servir d’Ember.

# app/controllers/home_controller.rb
class HomeController < ApplicationController
  def index
  end
end

# app/controllers/teams_controller.rb
class TeamsController < ApplicationController
  respond_to :json

  def index
    respond_with Team.all
  end
end

# app/models/team.rb
class Team < ActiveRecord::Base
  attr_accessible :city, :country, :name
end

# config/routes
MyAppName::Application.routes.draw do
  root :to => 'home#index'

  resources :teams
end

Dans un premier temps, nous allons ajouter une route dans le router d’EmberJS pour avoir une url afin de voir nos Teams :

# app/assets/javascripts/router.js.coffee
MyAppName.Router.map () ->
  @resource('teams')

Ceci va nous permettre d’accèder à l’url http://localhost:3000/#/teams qui listera les Teams présentent. Ensuite, nous créons le model EmberJS correspondant :

# app/assets/javascripts/models/team.js.coffee
MyAppName.Team = DS.Model.extend
  name: DS.attr('string')
  city: DS.attr('string')
  country: DS.attr('string')

Enfin, il faut ajouter un fichier de routes spécifique pour le model en question :

# app/assets/javascripts/routes/teams.js.coffee
MyAppName.TeamsRoute = Ember.Route.extend
  model: ->
    @store.find('team')

Il ne manque maintenant plus que le fichier de template pour afficher les informations souhaitées :

Liste des équipes

<ul>
{