diff --git a/D-poo-avancee.md b/D-poo-avancee.md index b2d724946722ed83561757c7ef021e2c3c737337..2e694e3ec6430f65dd633c23f02384234dc14870 100644 --- a/D-poo-avancee.md +++ b/D-poo-avancee.md @@ -1,21 +1,18 @@ -# TP 2 - POO - modules - typage <!-- omit in toc --> +# TP 2 : D. POO avancée <!-- omit in toc --> ## Sommaire <!-- omit in toc --> -- [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 document.querySelector('.pageTitle').innerHTML = title.render(); ``` -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 const c = new Component( 'span', null, [ - new Component( 'img', null, ['FTW'] ) 'JS', + new Component( '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'}, [ - new Img('images/regina.jpg'), - 'Regina' - ]); + const c = new Component( + 'article', + {name:'class', value:'media'}, + [ + new Img('images/regina.jpg'), + 'Regina' + ] + ); document.querySelector( '.pizzasContainer' ).innerHTML = c.render(); ``` 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 document.querySelector( '.pizzasContainer' ).innerHTML = pt.render(); ``` -## B.6. La classe HomePage +## D.2. La classe HomePage -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) \ No newline at end of file