Skip to content
Snippets Groups Projects
Commit d8449cc7 authored by Thomas Fritsch's avatar Thomas Fritsch
Browse files

maj poo avancée

parent 5dec32f5
Branches
No related tags found
No related merge requests found
# 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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment