-[E. Pour aller plus loin](#e-pour-aller-plus-loin)
-[B.5. *Composition :* La classe PizzaThumbnail](#b5-composition--la-classe-pizzathumbnail)
-[B.6. La classe HomePage](#b6-la-classe-homepage)
-[E.1. *Propriétés et méthodes statiques :* La classe PageRenderer](#e1-propriétés-et-méthodes-statiques--la-classe-pagerenderer)
-[E.2. *Setter & Getter :* La propriété `data`](#e2-setter--getter--la-propriété-data)
-[D.1. *Composition :* La classe PizzaThumbnail](#d1-composition--la-classe-pizzathumbnail)
-[D.2. La classe HomePage](#d2-la-classe-homepage)
-[D.3. *Propriétés et méthodes statiques :* La classe PageRenderer](#d3-propriétés-et-méthodes-statiques--la-classe-pagerenderer)
-[D.4. *Setter & Getter :* La propriété `data`](#d4-setter--getter--la-propriété-data)
-[Étape suivante](#Étape-suivante)
## E. Pour aller plus loin
Si vous avez terminé les précédents exercices voici qui devrait vous occuper et permettre de gagner du temps pour le prochain TP :
## D.1. *Composition :* La classe PizzaThumbnail
1.**Modifiez le code de la méthode `render()`** de la classe `Component` pour lui permettre de recevoir dans le paramètre `children` :
- soit une **chaîne de caractères** (comme c'est déjà le cas actuellement)
- soit un **tableau de chaînes de caractères.**<br>Par exemple : si `tag` vaut `"div"` et que `children` vaut `[ "youpi", "ça", "marche" ]` alors `render()` retournera la chaîne `"<div>youpiçamarche</div>"`.
## B.5. *Composition :* La classe PizzaThumbnail
1.**Modifiez le code de la méthode `render()`** pour permettre à la classe `Component` de recevoir dans le paramètre `children` :
- soit une chaîne de caractères (comme c'est déjà le cas actuellement)
- soit un tableau de chaînes de caractères.**<br>Par exemple : si `tag` vaut `"div"` et que `children` vaut `[ "youpi", "ça", "marche" ]` alors `render()` retournera la chaîne `"<div>youpiçamarche</div>"`.
Pour ne pas alourdir trop le code de la méthode `render()` et pour avoir un code plus lisible, passez le code de rendu des enfants, dans une méthode `renderChildren()`.
***NB :** Pour ne pas alourdir trop le code de la méthode `render()` et pour avoir un code plus lisible, passez le code de rendu des enfants, dans une méthode `renderChildren()`.*
Pour tester si `children` est un tableau (classe `Array`), vous pouvez utiliser l'opérateur `instanceof` cf. https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Op%C3%A9rateurs/instanceof
...
...
@@ -25,30 +22,34 @@ Si vous avez terminé les précédents exercices voici qui devrait vous occuper
2.**Adaptez la méthode `render()`** pour permettre de passer dans `children` non seulement des chaînes de caractères comme c'est déjà le cas mais aussi **d'autres `Component`**, comme ceci** :
2.**Adaptez la méthode `render()`** pour permettre de passer dans `children` non seulement des chaînes de caractères comme c'est déjà le cas mais aussi **d'autres `Component`**, comme ceci :
```js
constc=newComponent('span',null,[
newComponent('img',null,['FTW'])
'JS',
newComponent('strong',null,'FTW')
]);
```
La méthode `renderChildren()` devra maintenant tester le type de chaque enfant :
- si cet enfant est lui-même une instance de Component, on fait alors appel à la méthode `render()` du `Component` enfant (petit indice : "récursivité")
Pour cela, la méthode `renderChildren()` devra maintenant tester le type de chaque enfant :
- si cet enfant est lui-même une instance de Component, on fait alors appel à la méthode `render()` du `Component` enfant (petit indice : ça ressemble au concept de "récursivité")
- si l'enfant est une chaîne de caractères, alors la chaîne est ajoutée telle qu'elle, comme auparavant
Pour tester si un enfant est de la classe `Component`, vous pouvez là aussi utiliser l'opérateur `instanceof` cf. https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Op%C3%A9rateurs/instanceof
Si votre code fonctionne correctement, le code suivant :
```js
const c = new Component( 'article', {name:'class', value:'media'}, [
doit afficher la page suivante :<br><a href="images/readme/pizzaland-04.jpg"><img src="images/readme/pizzaland-04.jpg" width="80%"></a>
3.**Créez une classe `PizzaThumbnail`** qui hérite de la classe `Component` :
3.**Créez une classe `PizzaThumbnail`**(dans js/components/PizzaThumbnail.js`) qui hérite de la classe `Component` :
+ le constructeur prend en paramètre un objet nommé `pizza` dont le format correspond à celui d'un élément du tableau `data` (cad. propriétés `nom`, `base`, `prix_petite`, `prix_grande` et `image`)
+ la méthode `render()` retourne un code du type :
```html
...
...
@@ -72,32 +73,32 @@ Si vous avez terminé les précédents exercices voici qui devrait vous occuper
4.**Créez enfin une classe `HomePage` qui hérite de `Component`** :
- le constructeur recevra en paramètre le tableau `data`
-Pour chaque cellule du tableau`data`, le composant `HomePage` créera un composant `PizzaThumbnail` associé.
- le code HTML retourné par la méthode `render()` sera une balise `<section>` dans laquelle sera affichée la combinaison du `render()` de chaque `PizzaThumbnail` contenu dans la page.
1. **Créez une classe `HomePage` dans le fichier `js/pages/HomePage.js` qui hérite de `Component`** :
- le constructeur recevra en paramètre un tableau de pizzas
- pour chaque cellule du tableau, le composant `HomePage` créera un composant `PizzaThumbnail` associé
- le code HTML retourné par la méthode `render()` sera une balise `<section>` dans laquelle sera affichée la combinaison du `render()` de chaque `PizzaThumbnail`
***NB:** en théorie, un simple override du constructor et l'utilisation de la méthode [Array.map](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array/map) doivent suffire !*
Le résultat attendu est le suivant :<br><a href="images/readme/pizzaland-05.jpg"><img src="images/readme/pizzaland-05.jpg" width="80%"></a>
### E.1. *Propriétés et méthodes statiques :* La classe PageRenderer
1. Créez une classe `Page` (dans un module à part, bien entendu !) :
## D.3. *Propriétés et méthodes statiques :* La classe PageRenderer
1. Créez une classe `Page` (dans un module `js/pages/Page.js`) :
- qui hérite de `Component`
- dont le constructeur reçoit comme paramètres: title (string) et children
- `title` est enregistré dans une propriété d'instance privée
- la classe dispose d'une méthode `renderTitle()` qui retourne le titre passé au constructeur entouré d'une balise `<h1>...</h1>`
2. Modifiez la classe `HomePage` pour la faire hériter de `Page`. Son titre sera `'La carte'`.
3. Créez une classe PageRenderer avec :
- une propriété statique `titleElement` de type `:?HTMLElement`
- une propriété statique `contentElement` également de type `:?HTMLElement`
- une méthode statique `renderPage( page )` qui affiche dans `titleElement` le résultat de l'appel à la méthode `renderTitle()` et dans contentElement le résultat de l'appel à la méthode `render()` de la page passée en paramètre.
3. Créez une classe `PageRenderer` (dans un module `js/PageRenderer.js`) avec :
- une propriété statique `titleElement`
- une propriété statique `contentElement`
- une méthode statique `renderPage( page )` qui affiche dans `titleElement` le résultat de l'appel à la méthode `page.renderTitle()` et dans contentElement le résultat de l'appel à la méthode `page.render()` de la page passée en paramètre.
4. Assigner à `titleElement` : `document.querySelector('.pageTitle')` et à `contentElement` : `document.querySelector( '.pizzasContainer' )`
4. Afficher la `HomePage` grâce à la classe `PageRenderer`
5. Afficher la `HomePage` grâce à la classe `PageRenderer`
### E.2. *Setter & Getter :* La propriété `data`
## D.4. *Setter & Getter :* La propriété `data`
A l'aide des propriétés privées, des getters et des setters, faire en sorte que le code suivant permette d'afficher la liste des pizzas :
```js
let homePage:HomePage = new HomePage([]);
...
...
@@ -106,6 +107,5 @@ homePage.data = data;
PageRenderer.renderPage( homePage ); // affiche la liste des pizzas
```
***NB:** N'oubliez pas de typer toutes vos nouvelles classes au fur et à mesure (ne pas oublier non plus le commentaire `// @flow`) et de vérifier régulièrement que tout est conforme à l'aide de la commande `./node_modules/.bin/flow`*
voir comment renforcer le typage du code JS de notre application dans la partie suivante: [Le typage](D-typage.md)
\ No newline at end of file
## Étape suivante
Si vous êtes arrivés ici, bravo, il vous reste à voir comment on peut renforcer le typage du code notre application dans la partie suivante: [E. Le typage](E-typage.md)