Cet article nécessite une relecture rédactionnelle. Voici comment vous pouvez aider.
Cet article fournit une introduction basique aux concepts derrière le patron d'architecture logicielle Modèle Vue Contrôleur (MVC), puis explique comment il est implémenté par Ember.js - un framework populaire pour le développement d'applications web.
La théorie Modèle Vue Contrôleur
Modèle Vue Contrôleur (MVC) est un patron d'architecture logicielle, généralement utilisé pour implémenter des interfaces utilisateurs: c'est donc un choix populaire pour la conception d'applications web. En général, on sépare l'application en trois parts distinctes, permettant la modularité et rendant plus simple la collaboration et la ré-utilisation. Ce modèle rend aussi les applications plus flexibles et plus accueillantes aux itérations.
Pour faire simple, imaginons une application web simple pour faire des achats. Tout ce que nous voulons est une liste du nom, de la quantité et du prix de chaque produit que nous avons besoin d'acheter cette semaine. Ci-dessous, nous allons décrire comment nous pouvons implémenter certaine de ces fonctionnalités en utilisant MVC.
Le Modèle
Le modèle détermine quelles données l'application doit contenir. Si l'état de ces données change, alors le modèle va généralement avertir la vue (donc l'affichage peut changer au besoin) et parfois le contrôleur (dans la cas où une logique différente est nécesssaire pour contrôler la modification de la vue).
Si on revient à notre application d'achat, le modèle va spécifier quelles données la liste des éléments doit contenir: l'élement, le prix, etc. — et quels éléments de cette liste y sont déjà présents.
La Vue
La vue détermine comment les données de l'application doivent être affichées.
Dans notre application web d'achat, la vue va définir comment la liste sera présentée à l'utilisateur, c'est elle qui va recevoir les données du modèle pour les afficher.
Le Contrôleur
Le contrôleur contient toute la logique de mise à jour du modèle et/ou la vue en réponse aux entrées (actions) de l'utilisateur sur l'application.
Donc par exemple, notre application d'achat va contenir des formulaires de saisie et des boutons pour ajouter ou supprimer des élements. Ces actions nécessitent au modèle d'être mis à jour, ainsi la saisie est envoyée au contrôleur, qui va manipuler le modèle approprié, puis va envoyer la donnée mise à jour vers la vue.
Vous souhaiterez peut être juste mettre à jour la vue afin d'afficher l'information dans un format différent, par exemple changer le tri des élements par ordre alphabétiqu, ou par ordre de prix décroissant. Dans ce cas le contrôleur peut saisir ça directement, sans avoir besoin de mettre à jour le modèle.
Évolution du MVC sur le web
En tant que développeur web, ce patron de conception vous sera probablement familier même si vous ne l'avez jamais consciemment utilisé auparavent. Votre modèle de données est probablement contenu dans une sorte de base de données (cela peut être une base de données client-server traditionnelle comme MySQL, ou une solution côté client comme IndexedDB). Le code de contrôle de l'application est probablement écrit en HTML/JavaScript, et l'interface utilisateur est probablement écrite en utilisant HTML/CSS/quoique-ce-soit d'autre que vous souhaitez. Cela ressemble de près à du MVC, mais MVC fait que ces composants vont suivre un modèle plus rigide.
Dans les premiers jours du Web, l'architecture MVC était majoritairement implémentée du coté serveur, avec le client qui demandait des mises à jour via des formulaires ou des liens, et recevait en retour la modification de ses vues pour les afficher dans le navigateur. Cependant, de nos jours, davantage de logique métier est rammenée vers le client avec l'avènement des stockages de données côté client, et de XMLHttpRequest qui permet la mise à jour partielle de la page quand elle est nécessaire.
Les frameworks web populaires comme AngularJS, Ember.js ou Backbone implémentent tous l'architecture MVC, mais de façon légèrement différente.
Comment Ember.js utilise le MVC dans la pratique
Ember — le framework que nous allons utiliser pour cette série — implémente le MVC suivant un ensemble stricte de concepts et de règles; ce document fournit un bref résumé de ce que nous avons besoin de savoir pour l'instant. Vous pouvez en apprendre plus en lisant la documentation d'Ember — un bon point de départ est la partie Concepts de base.
Vous devez aussi vous familiarisez avec la convention de nommage d'Ember, qui sont strictement appliquées afin de permettre des objets associés de facilement parler les uns aux autres, sans trop de fioritures supplémentaire pour les relier entre eux.
Enfin, vu que nous utilisons Ember CLI pour automatiser beaucoup de ses processus, vous devriez garder la documentation Ember CLI sous la main.
La couche Vue dans Ember
Dans Ember, les vues sont légèrement différentes de comment elles sont en général dans MVC. Dans les termes MVC, nous pensons souvent que la vue est "toute la couche interface utilisateur", alors que dans Ember une vue est un composant spécifique de l'UI, tout comme les routes et les templates.
Une interface Ember.js typique et simple utilise des objets Route et des fichiers de template pour traiter la Vue. Les Routes spécifient l'URL à partir de laquelle le template est acessible par vos utilisateurs, et peut aussi spécifier quel Modèle le template doit utiliser pour afficher ses données. Chaque route est représentée par un fichier JavaScript. Les templates définissent à quoi ressemble l'interface, est sont représentés par des fichiers de template Handlebars (.hbs
). Ces fichiers sont du HTML contenant des expressions dynamiques spéciales, utilisant des accolades doubles ({{ ... }}
). Les accolades doubles, sous leur forme simple, peuvent récupèrer les données/propriétés contenues dans le Modèle (ou Contrôleur) et les afficher dans l'interface, par exemple:
<div class="entry"> <h1>{{title}}</h1> <div class="body"> {{body}} </div> </div>
Ces propriétés vont se mettre à jour automatiquement dans le template quand le Modèle/Contrôleur va changer.
Ember CLI peut générer une route et associer un template en utilisant la commande suivante:
ember generate route mon-nom-de-route
Cette commande va générer:
- Un fichier JavaScript dans
racine-de-l-application/app/routes
pour contrôler la route. - Un fichier de template Handlebars dans
racine-de-l-application/app/templates
pour définir le contenu qui s'affichera pour l'URL nommée. - Un fichier de test unitaire dans
racine-de-l-application/tests/unit/routes
où il est possible de définir un test pour la fonctionnalité de votre route.
Le fichier de route va contenir un squelette basique pour débuter l'écriture de la logique de la route:
import Ember from 'ember'; export default Ember.Route.extend({ // les fonctionnalités requises });
Comme beaucoup d'autres frameworks MVC, Ember fournit une fondation de structure pour l'application que vous pouvez personnaliser et étendre en fonction des besoins de cette application. Ce code importe l'objet principal Ember
, et vous permet de construire vos fonctionnalités sur l'objet interne Route
en appelant sa méthode extend
. C'est un patron de développement très courant que vous allez commencer à reconnaitre durant la construction de votre application.
Les fichiers route et template vont tout deux porter le même nom, par exemple shopping-list.js
et shopping-list.hbs
, ils sont associés par défaut; la vue est donc disponible à l'utilisateur à l'adresse votre-serveur.com/shopping-list/
(ou quelque-soit le nom que vous avez donné).
Les contrôleurs Ember
Ember.js réprésente les contrôleurs en utilisant des objets controller, qui sont contenus dans des fichiers JavaScript.
Ember CLI peut générer un contrôleur en utilisant la syntaxe suivante :
ember generate controller nom-du-controleur
Ceci va créer deux nouveaux fichiers:
- Un fichier JavaScript dans
racine-de-l-application/app/controllers
pour contrôler le modèle ou la vue particulière. - Un fichier de test unitaire dans
racine-de-l-application/tests/unit/controllers
où vous pouvez définir un test de la fonction de votre contrôleur.
Donc pour notre exemple de liste d'achats, si nous avons déjà une route et un template nommés shopping-list
, il est judicieux de créer un contrôleur appelé shopping-list
. Ce nommage permet d'associer automatiquement ce contrôleur avec la bonne route et/ou le bon modèle.
Le fichier contrôleur généré contient:
import Ember from 'ember'; export default Ember.Controller.extend({ // les fonctionnalités requises });
Tout comme pour notre route, notre contrôleur importe l'objet principal Ember
et étend l'objet par défault Controller
pour nous permettre de créer notre propre contrôleur personnalisé qui fera ce que nous souhaitons.
Les modèles Ember
Ember.js représente les Modèles en utilisant des objets model, qui, comme précédemment, sont contenus dans des fichiers JavaScript.
Ember CLI peut générer un modèle avec la syntaxe suivante:
ember generate model nom-de-mon-modele
Ceci va créer deux nouveaux fichiers:
- Un fichier JavaScript dans
racine-de-l-application/app/models
pour définir les données à associées avec cette vue spécifique. - Un fichier de test unitaire dans
racine-de-l-application/tests/unit/models
où vous pouvez définir un test de la fonction de votre modèle.
Donc pour notre exemple de liste d'achats, il est encore judicieux de créer un modèle nommé shopping-list
. Ce nommage permet d'associer automatiquement ce modèle avec la bonne route et/ou le bon contrôleur .
Le fichier modèle généré contient:
import DS from 'ember-data'; export default DS.Model.extend({ // les fonctionnalités requises });
Tout comme pour notre route et notre contrôleur, notre modèle importe l'objet principal Ember
et étend l'objet par défault Model
pour nous permettre de créer notre propre modèle personnalisé qui fera ce que nous souhaitons.
Suite
Maintenant que nous avons passé cette courte théorie à propos du MVC et de son implémentation dans Ember, nous allons appliquer ceci en pratique et construire une vraie application MVC basée sur Ember.