:: Enseignements :: ESIPE :: E3INFO :: 2020-2021 :: Programmation Web avec JavaScript ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) |
Examen Prog Web - Sujet 5 - Session 2
|
Le but de ce TP noté est d'écrire une version simplifié d'une librarie réactive de manipulation du DOM.
Voilà le code de la page HTML,
exam.html, que l'on veut afficher
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8"/>
<script src="exam.js" defer></script>
</head>
<body>
<div id = "my_node">
</div>
</body>
</html>
ainsi que le fichier
exam.js
// Ecrire le reste du code ici !
render({
state: 0,
view: state =>
v("div", {}, [
v("h1", { class: "red" }, state),
v("button", { onclick: state => state - 1 }, "subtract"),
v("button", { onclick: state => state + 1 }, "add")
]),
node: document.getElementById("my_node")
});
Exercice 1 - virtual domination
Une application réactive est une application qui change sont affichage en fonction du changement
de valeur d'un objet particulier qui correspond à l'état de l'application.
Par exemple, une application simple qui affiche une valeur avec un bouton + et -
pour incrémenter ou décrémenter la valeur auro pour état un simple entier
tandis que des application plus compliquées utiliseront des listes ou des objets comme état.
Une application réactive est composée de 3 valeurs différentes, l'état dont nous venons de parler,
la vue qui permet à partir de l'état de générer un arbre DOM qui sera affiché (une fonction donc)
et enfin un objet DOM de la page HTML qui va être remplacer par l'arbre DOM généré par la vue.
Donc de façon rudimentaire, l'application réactive qui incrémente et décrémente un entier peut se
décrire par l'object JavaScript suivant :
{
state: 0,
view: state => ... ,
node: document.getElementById("my_node")
}
Reste à savoir comment créer l'arbre DOM correspondant à l'état (les ... dans l'exemple, ci-dessus),
on se propose pour cela d'utiliser ce que l'on appel un
virtual DOM qui est un arbre
comme l'arbre DOM mais géré en JavaScript (contrairement à un arbre DOM qui est géré en C et
visible en JavaScript).
Voici un exemple de
virtual DOM
v("div", {}, [
v("h1", { class: "red" }, state),
v("button", { onclick: state => state - 1 }, "subtract"),
v("button", { onclick: state => state + 1 }, "add")
])
La fonction
v prend 3 paramètres, un nom d'élement (ici, div, h1 ou button), un ensemble
de propriété qui sont les propriétés de l'élément (par exemple la class de l'élement h1 ou la propriété
onclick) et enfin une valeur qui peut être soit un élément, soit un tableau d'élements
soit une valeur qui va être transformé en string pour être affiché.
Pour notre implantation, la fonction
v va renvoyer une instance de la classe
Element
ayant les attributs
name (le nom de l'élement),
properties un objet contenant les
propriétés de l'élements et
textOrChildren qui contient soit un élément, un tableau d'élements
ou une valeur.
De plus, la classe
Element va possèder une méthode
toDOM qui permet à partir
d'une élement du
virtual-dom de transformer celui-ci en élement réel du DOM
créer en utilisant les méthode habituelles
document.createElement,
document.createTextElement et
element.appendChild.
On peut noter que la fonction prise en paramètre par
onclick n'est pas la fonction classique
prise par la propriété
onclick sur l'arbre DOM, en effet, c'est fonction est ajouter
sur le
virtual dom pas usr le DOM généré.
La fonction classique
onclick enregistrer lors de la génération de l'arbre DOM
par la méthode
toDOM va appeler la fonction du
virtual dom avec en paramétre
l'état de l'application, puis stocker le résultat de l'appel dans le champs
state
et enfin appeler la fonction
render pour changer l'affichage graphique.
Cette astuce permet d'être sur que lorsque l'on clique sur un bouton, l'état de l'application
est mis à jour et que l'affichage graphique est raffraichi.
Si on met les différentes parties ensemble, on obtient le code suivant :
render({
state: 0,
view: state =>
v("div", {}, [
v("h1", { class: "red" }, state),
v("button", { onclick: state => state - 1 }, "subtract"),
v("button", { onclick: state => state + 1 }, "add")
]),
node: document.getElementById("my_node")
});
Lors de l'affichage de la page, la fonction
render prend l'objet correspondant à l'application,
récupère la valeur de l'état, appel la fonction
view pour créer l'arbre d'élements
(le
virtual dom, appel la méthode
toDOM sur l'arbre d'élement pour créer l'arbre DOM
correspondant puis remplace l'objet
node par le noeud racine de l'arbre DOM créé
(le remplacement se fait en demandant le
parentNode de
node puis en appelant la méthode
replaceChild() sur le parent).
Le code JavaScript doit utiliser la version JavaScript 2015.
-
Ecrire la classe Element et son constructeur. Ecrire la fonction v
qui renvoie une nouvelle instance de la classe Element à chaque appel.
-
Ecrire dans la classe Element la méthode toDOM et vérifier
avec un exemple sans gestion des évènements que l'arbre DOM généré est correct.
Note: Array.isArray permet de savoir si un objet est un tableau et
value instanceof Element permet de savoir si la variable value est un Element.
-
Ecrire la fonction render et vérifier que l'affichage de la page HTML
affiche bien l'arbre DOM générer.
-
Ajouter la gestion des évènements de tel sorte à ce que l'exemple ou l'on incrémente et décremente
une valeur ci-dessus fonctionne.
Note: value instanceof Function permet de savoir si la variable value est une fonction.
© Université de Marne-la-Vallée