Commit f2bf972dd80233cb168413d8a5cbed78b7e2d13f

Authored by Rémi Emonet
1 parent d5d1cc9a32
Exists in master

go

Showing 12 changed files with 582 additions and 27 deletions

cours-06.html View file @ f2bf972
... ... @@ -362,33 +362,6 @@
362 362 - @anim: .anonymous>span:nth-of-type(5), .anonymous>span:nth-of-type(6)
363 363  
364 364  
365   -## Objets et Classes JS {libyli}
366   -- JS n'est pas un langage orienté classe (Java)
367   -- JS est un langage à prototype
368   -- Très dynamique
369   -- Attention à `this` (≠ Java)
370   - - un objet « contexte »
371   - - pas nécessairement d'un type donné (comme la classe)
372   -- Plus flexible que les langages à classes
373   -- Le mot clé `class` arrive en ES6 ;-(
374   -
375   -
376   -## ES6 (ES2015) {libyli}
377   -- Syntaxe : class
378   - - `constructor()`, `super()`
379   - - `get`, `set`
380   -- Syntaxes
381   - - Modifieurs et portées de variables : const, var, val, let
382   - - *Arrow Functions* et gestion du `this`
383   - - Interpolation de string `\`Hello ${name}\``
384   - - Propriétés : raccourcis, méthodes, prop. construire (`[ «» ] : «»`)
385   - - Construction et déconstruction pour listes et objets (avec valeur par défaut et y compris en param)
386   - - *Rest* et *Spread* avec `...` (y compris en paramètre, syntactic sugar pour `arguments`)
387   - - Paramètres par défaut `a=2`
388   -- Autres : modules, generator
389   -- <a href="http://es6-features.org/" target="_blank">etc.</a>
390   -
391   -
392 365  
393 366  
394 367  
cours-07.html View file @ f2bf972
  1 +<!DOCTYPE html>
  2 +<html>
  3 + <head>
  4 + <meta charset="utf-8">
  5 + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6 +
  7 + <title>Programmation Web Avancée   vue, vuex, REST</title>
  8 + <meta name="cours-n" content="7">
  9 +
  10 + <meta name="author" content="Rémi Emonet">
  11 + <meta name="venue" content="PWA M1 DSC">
  12 + <meta name="date" content="2017">
  13 + <meta name="affiliation" content="Université Jean Monnet − Laboratoire Hubert Curien">
  14 +
  15 + <style type="text/css">
  16 + .slide.densish>ul {font-size: 70%;}
  17 + .commented-fs p {margin: 1em; }
  18 + .frflag {
  19 + background-image: url(media/frflag.svg);
  20 + width: 1em;
  21 + height: .75em;
  22 + display: inline-block;
  23 + background-size: contain;
  24 + }
  25 + </style>
  26 +
  27 + <!--
  28 + <script src="deck.js/extensions/includedeck/load.js"></script>
  29 + <script src="extensions/slides-dev.js"></script>
  30 + -->
  31 + <script src="extensions/deck-packed.js"></script>
  32 + <script src="extensions/slides.js"></script>
  33 + <script>go()</script>
  34 + </head>
  35 +
  36 +<body>
  37 +
  38 +<div class="deck-container">
  39 +
  40 + <div class="deck-loading-splash" style="background: black; color: chartreuse;"><span class="vcenter" style="font-size: 30px; font-family: Arial; ">Please wait, while our marmots are preparing the hot chocolate…</span></div>
  41 +
  42 +<section class="smart">
  43 +
  44 +# @chunk: chunks/title.md
  45 +
  46 +# Questions ? <br/> Commentaires ? {no-print}
  47 +
  48 +# @chunk: chunks/objectives.md
  49 +
  50 +## Programmation Web Avancée <span>{var-cours-n}</span> : Plan {#plan overview}
  51 +- Javascript {rappeljs}
  52 +- Vue : les bases {vue}
  53 +- Vue : composants {vuecomp}
  54 +- Principes REST {rest}
  55 +- Serveur REST en Spring {springrest}
  56 +- Client REST JSON en Vue {restjs}
  57 +# @copy:#plan
  58 +
  59 +
  60 +
  61 +<!-- ################################### -->
  62 +# @copy:#plan: %+class:inred: .rappeljs
  63 +
  64 +# <a href="cours-06.html#slide-59" target="_blank">slides précédents</a>
  65 +
  66 +## Fonctions JS {libyli}
  67 +- Fonction nommée « classique » en JavaScript
  68 +```javascript
  69 +function toto(a,b) {
  70 + return a+b;
  71 +}
  72 +alert(toto(1,3));
  73 +{dense slide}
  74 +```
  75 +- Fonction JavaScript : objet de première classe
  76 +```javascript
  77 +var f = function(a) {
  78 + return a*a;
  79 +}
  80 +alert(f(2));
  81 +var squares = [1,2,3].map(f);
  82 +{dense slide firstorder}
  83 +```
  84 +- @anim: .firstorder>span:nth-of-type(4) | .firstorder>span:nth-of-type(5)
  85 +- Fonction anonyme
  86 +```javascript
  87 +var squares = [1,2,3].map(function(a) {
  88 + return a*a;
  89 +});
  90 +
  91 +setTimeout(function() { alert("Hello"); },
  92 + 3000);
  93 +{dense slide anonymous}
  94 +```
  95 +- @anim: .anonymous>span:nth-of-type(5), .anonymous>span:nth-of-type(6)
  96 +
  97 +
  98 +## Objets et Classes JS {libyli}
  99 +- JS n'est pas un langage orienté classe (Java)
  100 +- JS est un langage à prototype
  101 +- Très dynamique
  102 +- Attention à `this` (&ne; Java)
  103 + - un objet « contexte »
  104 + - pas nécessairement d'un type donné (comme la classe)
  105 +- Plus flexible que les langages à classes
  106 +- Le mot clé `class` arrive en ES6 ;-(
  107 +
  108 +
  109 +## ES6 (ES2015) {libyli}
  110 +- Syntaxe : class
  111 + - `constructor()`, `super()`
  112 + - `get`, `set`
  113 +- Syntaxes
  114 + - Modifieurs et portées de variables : const, var, val, let
  115 + - *Arrow Functions* et gestion du `this`
  116 + - Interpolation de string `̀ Hello ${name}̀ ` (backticks)
  117 + - Propriétés : raccourcis, méthodes, prop. construire (`[ «» ] : «»`)
  118 + - Construction et déconstruction pour listes et objets (avec valeur par défaut et y compris en param)
  119 + - *Rest* et *Spread* avec `...` (y compris en paramètre, syntactic sugar pour `arguments`)
  120 + - Paramètres par défaut `a=2`
  121 +- Autres : modules, generator
  122 +- <a href="http://es6-features.org/" target="_blank">etc.</a>
  123 +
  124 +## Gestion du `this` et *Arrow Functions* (ES6) {libyli}
  125 +- Attention à `this` (&ne; Java)
  126 + - un objet « contexte » variable
  127 + - pas nécessairement d'un type donné (comme la classe)
  128 +```javascript
  129 +var o = {
  130 + i: 10000,
  131 + test: function() {
  132 +
  133 + this.incr = function() {
  134 + this.i += 1;
  135 + console.log(this.i);
  136 + };
  137 +
  138 + this.incr2 = () => {
  139 + this.i += 1;
  140 + console.log(this.i);
  141 + };
  142 +
  143 + this.incr();
  144 + this.incr2();
  145 + setTimeout(this.incr, 300); // executer 300 ms plus tard
  146 + // TODO: .bind(this)
  147 + setTimeout(this.incr2, 600); // executer 600 ms plus tard
  148 + },
  149 +};
  150 +
  151 +o.test();
  152 +{slide dense}
  153 +```
  154 +
  155 +<!-- ################################### -->
  156 +# @copy:#plan: %+class:inred: .vue
  157 +
  158 +# Sans <span style="font-size: 50%">et avec</span> Vue :<br/> des champs synchronisés
  159 +
  160 +## Ce qu'on a utilisé
  161 +- Javascript
  162 + - `Array.from()`, `document.querySelectorAll`, `.forEach`
  163 + - `Math.random()`
  164 + - `.oninput`, `.tagName`, `.value`, `.textContent`
  165 +- CSS (`background`, `border`, `padding`)
  166 +
  167 +## Vue / Vuex
  168 +- Vue
  169 + - framework léger pour applications interactives coté client
  170 + - similarité avec Angular, React, Ember, ...
  171 + - approche composant avec bindings
  172 + - <a href="https://vuejs.org/v2/guide/" target="_blank">https://vuejs.org/v2/guide/</a>
  173 + - <a href="https://fr.vuejs.org/v2/guide/index.html" target="_blank">https://fr.vuejs.org/v2/guide/index.html</a> <span class="frflag"/>
  174 +- Vuex
  175 + - <a href="https://vuex.vuejs.org/en/" target="_blank">https://vuex.vuejs.org/en/</a>
  176 + - <a href="https://vuex.vuejs.org/fr/" target="_blank">https://vuex.vuejs.org/fr/</a> <span class="frflag"/>
  177 +
  178 +# <span style="font-size: 50%">Sans et</span> avec Vue :<br/> des champs synchronisés
  179 +
  180 +## Vue : Principes {libyli}
  181 +- Données observables, rendu automatiquement à jour
  182 +- Template HTML+CSS
  183 + - avec des moustaches `{{ ... }}{}` (n'importe quelle expression ecmascript)
  184 + - avec des directives *vue*, éléments avec des attributs `v-...`
  185 + - accès automatique au *ViewModel*
  186 +- Objet javascript de type `Vue`
  187 +```javascript
  188 +var vm = new Vue({
  189 + el: ..., // selecteur CSS de l'élément à traiter
  190 + data: { // objet contenant l'état / les données / le ViewModel
  191 + ...
  192 + },
  193 + methods: { // les actions / le comportement
  194 + ...
  195 + },
  196 + computed: { // des fonctions, chacune renvoie une propriété calculée
  197 + ... // possibilité de {get: ..., set: ...} pour un mutateur calculé
  198 + },
  199 + watch: { // listener quand une des propriétés de data change
  200 + ...
  201 + }
  202 +});
  203 +{slide dense}
  204 +```
  205 +
  206 +## Vue : Liaison unidirectionnelle {libyli}
  207 +- Comme les moustaches mais pour des attributs
  208 +- Utlisation de `v-bind:...` ou `:...`
  209 +- Cas des attributs booléen (présent ou non dans le DOM), e.g. `:disabled="ind==0"`
  210 +
  211 +
  212 +## Vue : Liaison avec des formulaires {libyli}
  213 +- Pour les éléments éditables (input, select ou textarea)
  214 +- Liaison bidirectionnelle (de la propriété `value` de ces éléments)
  215 +- Attribut `v-model="..."`
  216 +- Valeur : nom de la propriété de l'état
  217 +- Modificateurs en suffixe `.lazy`, `.number`, `.trim`
  218 +
  219 +## Vue : Gestion des événements {libyli}
  220 +- Événements avec attributs `v-on:...` (ou `@...`)
  221 +- Valeur de l'attribut
  222 + - nom de la méthode
  223 + - ou, code à exécuter
  224 +- Modificateurs en suffixe
  225 + - gestion de l'événement : `.stop`, `.prevent`, `.once`, ...
  226 + - pour les touches et/ou click souris : `.shift`, `.ctrl`, `.exact`, ...,
  227 + - pour spécifier une touche : `.enter`, `.up`, `.space`, `.65`, ...,
  228 + - pour spécifier un bouton de la souris : `.left`, `.middle`, `.right`
  229 +
  230 +```
  231 +<a v-on:click="go" v-on:mousemove.ctrl="go()">click ou ctrl+mouvement</a>
  232 +
  233 +<a     @click="go"     @mousemove.ctrl="go()">click ou ctrl+mouvement</a>
  234 +{slide denser}
  235 +```
  236 +
  237 +## Vue : conditions et itérations {libyli}
  238 +- Affichage conditionnel avec `v-if="..."`
  239 + - expression booléene décidant du rendu ou non de l'élément
  240 + - NB: l'élément n'est alors pas dans le DOM
  241 +- Affichage en boucle (comme Thymeleaf) avec `v-for="vvv in lll"`
  242 + - nom de variable arbitraire
  243 + - possibilité d'avoir auss l'indice avec `(vvv, iii) in lll`
  244 +
  245 +## Vue : Autre
  246 +- Variables de contexte selon les cas: `$index` (boucles), `$event` (listener), ...
  247 +
  248 +
  249 +
  250 +
  251 +
  252 +<!-- ################################### -->
  253 +# @copy:#plan: %+class:inred: .vuecomp
  254 +
  255 +## Vue : Composants {libyli}
  256 +- But
  257 + - encapsuler un rendu et/ou comportement
  258 + - créer ses propres éléments, par ex, `〈pwa year="2017"〉Rocks〈/pwa〉{dense}`
  259 +- Fonction `Vue.component`
  260 + - `props`: liste des attributs attendus
  261 + - `template`: template HTML
  262 + - attention, `data` doit être une fonction (si présent)
  263 +```
  264 +Vue.component('nom-du-tag', {
  265 + props: ['msg'],
  266 + template: '<div>{{ msg }}</div>',
  267 + data: function () {
  268 + return {
  269 + ...
  270 + }
  271 + },
  272 + });
  273 +{slide}
  274 +```
  275 +- Utilisation
  276 +```
  277 + <nom-du-tag msg="Salut"></nom-du-tag>
  278 + <nom-du-tag v-bind:msg="leMessage"></nom-du-tag>
  279 +{slide}
  280 +```
  281 +
  282 +## Vue : Émettre des événements depuis un composant {libyli}
  283 +- Dans le composant
  284 + - utilisation de la fonction `$emit`
  285 + - par ex : `$emit('truc')`
  286 +- Dans le parent, ecoute classique
  287 + - par ex : `v-on:truc` ou `@truc`
  288 +- Possibilité d'utiliser `v-model` (bidirectionnel)
  289 + - avoir une prop `value`
  290 + - émettre des événements `input` (`this.$emit('input', v)`)
  291 +
  292 +## Vue : à voir
  293 +- composants dans un fichier `.vue` (pas de `template:'....'`)
  294 +- transition / animations
  295 +- packaging
  296 +- vue cli : ligne de commande
  297 +- vuex : gestion d'état centralisé
  298 +- routeur : url, bookmarking, deep linking
  299 +- directives perso
  300 +
  301 +<!-- ################################### -->
  302 +# @copy:#plan: %+class:inred: .rest
  303 +
  304 +# Principes REST : *Representational State Transfer*
  305 +
  306 +## *Representational State Transfer* {libyli}
  307 +- <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm">Thèse de Roy T. Fielding</a> (et <a href="http://opikanoba.org/tr/fielding/rest/">[fr]</a>)
  308 +- Un style d'architecture
  309 + - un ensemble de ressources
  310 + - des liens entre ces ressources
  311 + - comme une bonne application Web
  312 + - Hypermedia as the engine of application state (HATEOAS) {slide} // important : le client choisi ce qu'il fait, le serveur guide
  313 +- Propriété et objectifs
  314 + - performance et passage à l'échelle // cacheable
  315 + - simplicité et évolutivité
  316 +- Principes {libyli}
  317 + - client-serveur, *stateless* (sans état), couches (cache, sécurité, ...) // ne sait pas si on parle au serveur directement
  318 + - ressources auto-décrites avec identifiant et métadonnées, HATEOAS
  319 +- <a href="http://www.figer.com/Publications/REST.htm">Résumé en Français</a>
  320 +
  321 +## *RESTful HTTP APIs* : REST sur HTTP {libyli} // RESTful (adjectif de REST)
  322 +- Ressource : identifiant et représentation
  323 + - URI (*Unique Resource Identifier*), `https://github.com/apache/spark {dense}`
  324 + - métadonnées, ex : `Content-Type: text/html{dense}`, `Content-Encoding: gzip{dense}`
  325 + - données, ex : HTML gzippé
  326 +-   {no}
  327 + - NB : pas de verbes ou actions dans les URI // capital !
  328 + - ok : `https://github.com/repositories`
  329 + - ko : `https://github.com/createNewRepo?name=pwa`
  330 +- Protocole *stateless* : HTTP avec méthodes HTTP {libyli}
  331 + - GET : sûre (sans effets de bords)
  332 + - récupère la représentation d'une ressource
  333 + - liste le contenu d'une collection
  334 + - DELETE : idempotente (même résultat si appliqué plusieurs fois)
  335 + - supprime une ressource existante
  336 + - supprime une collection
  337 + - PUT : idempotente
  338 + - remplace ou met à jour une ressource
  339 + - remplace ou met à jour une collection
  340 + - POST :
  341 + - crée une nouvelle entrée dans une collection
  342 +
  343 +
  344 +
  345 +
  346 +
  347 +<!-- ################################### -->
  348 +# @copy:#plan: %+class:inred: .springrest
  349 +
  350 +# <a href="https://spring.io/guides/tutorials/react-and-spring-data-rest/" target="_blank">(Tutoriel Spring+REST+React)</a>
  351 +
  352 +## Création d'un Modèle REST en Spring {libyli}
  353 +- {no}
  354 + - But : partager un modèle JPA en REST, au format JSON
  355 +- Étapes
  356 + - modèle : entités JPA
  357 + - service : repository `JpaRepository` (ou `CrudRepository`)
  358 + - `spring-data-rest-webmvc` (dépendance maven)
  359 + - ou à la main avec `@RestController`, `@Valid`, `RequestMethod.*`
  360 + - (configuration : `spring.data.rest.basePath=/api`)
  361 + - si client à une autre url : *Cross-origin resource sharing* (<a href="http://en.wikipedia.org/wiki/Cross-origin_resource_sharing">CORS</a>)
  362 +- Test simplifiés
  363 +```
  364 + curl -X GET http://localhost:8080/api/hotels
  365 + curl -X POST http://localhost:8080/api/hotels -H "Content-Type: application/json" -d '{"name":"ibis", "nrooms":444}'
  366 + curl -X GET http://localhost:8080/api/hotels
  367 + curl -X GET http://localhost:8080/api/hotels/ibis
  368 + curl -X DELETE http://localhost:8080/api/hotels/ibis
  369 + curl -X GET http://localhost:8080/api/hotels
  370 +{denser slide}
  371 +```
  372 +- {no}
  373 + - Let's do it ! (hotels)
  374 + - (plugin JSONView + cfg content `application/hal+json`)
  375 +
  376 +<!-- ################################### -->
  377 +# @copy:#plan: %+class:inred: .restjs
  378 +
  379 +# à venir
  380 +
  381 +
  382 +
  383 +
  384 +</section>
  385 +
  386 + <!-- deck.status snippet -->
  387 + <p class="deck-status deck-progress-10"> <span class="deck-status-current"></span> / <span class="deck-status-total"></span> − <span class="var-author">will be replaced by the author</span> − <span class="var-title">will be replaced by the title</span></p>
  388 +
  389 + <a data-progress-size=": spe.top(15, 555); height: 45*designRatio; left: slide.right - 90*designRatio; width: 90*designRatio" class="ccby" href="http://en.wikipedia.org/wiki/Creative_Commons_license" title="This work is under CC-BY licence." target="_blank"></a>
  390 +
  391 + <a class="ujm" data-progress-size=": spe.top(15, 525); height: 65*designRatio; left: slide.left; width: 130*designRatio" target="_blank"></a>
  392 +
  393 +</div>
  394 +<!-- clicky Cla -->
  395 +<script type="text/javascript">
  396 +var clicky_site_ids = clicky_site_ids || [];
  397 +clicky_site_ids.push(100779706);
  398 +(function() {
  399 + var s = document.createElement('script');
  400 + s.type = 'text/javascript';
  401 + s.async = true;
  402 + s.src = '//static.getclicky.com/js';
  403 + ( document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0] ).appendChild( s );
  404 +})();
  405 +</script>
  406 +<noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/100779706ns.gif" /></p></noscript>
  407 +
  408 +
  409 +<!-- Histats.com START (aync)-->
  410 +<script type="text/javascript">var _Hasync= _Hasync|| [];
  411 +_Hasync.push(['Histats.start', '1,2767123,4,0,0,0,00010000']);
  412 +_Hasync.push(['Histats.fasi', '1']);
  413 +_Hasync.push(['Histats.track_hits', '']);
  414 +(function() {
  415 +var hs = document.createElement('script'); hs.type = 'text/javascript'; hs.async = true;
  416 +hs.src = ('http://s10.histats.com/js15_as.js');
  417 +(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(hs);
  418 +})();</script>
  419 +<noscript><a href="http://www.histats.com" target="_blank"><img src="http://sstatic1.histats.com/0.gif?2767123&101" alt="javascript hit counter" border="0"></a></noscript>
  420 +<!-- Histats.com END -->
  421 +</body>
  422 +</html>
... ... @@ -57,6 +57,9 @@
57 57 <div>
58 58 <a class="tile" data-code-date="09-13"></a>
59 59 <a class="tile" data-code-date="09-29"></a>
  60 + <a class="tile" data-code-date="10-13"></a>
  61 + <a class="tile" data-code-date="10-20-js"></a>
  62 + <a class="tile" data-code-date="10-20-api"></a>
60 63 </div>
61 64 <!--
62 65 <a href="raw/cours-2.zip">Fichiers HTML et CSS du cours</a>
js-examples/js-functions-superpow.js View file @ f2bf972
  1 +
  2 +
  3 +const superpow = (f, n) => (x) => {
  4 + var i = n; // copy to avoid sharing
  5 + var r = f(x);
  6 + while (i>1) {
  7 + i--;
  8 + r = f(r);
  9 + }
  10 + return r;
  11 +};
  12 +
  13 +const f = (x) => x*x;
  14 +const f3 = superpow(f, 3)
  15 +
  16 +console.log(f3(2))
  17 +console.log(f3(2))
  18 +
  19 +console.log([1, 2, 3, 4, 5].map(f3))
  20 +
  21 +console.log([1, 2, 3, 4, 5].map( superpow(f, 2) ))
js-examples/js-functions-this-minimal.js View file @ f2bf972
  1 +var o = {
  2 + i: 10000,
  3 + test: function() {
  4 +
  5 + this.incr = function() {
  6 + this.i += 1;
  7 + console.log(this.i);
  8 + };
  9 +
  10 + this.incr2 = () => {
  11 + this.i += 1;
  12 + console.log(this.i);
  13 + };
  14 +
  15 + this.incr();
  16 + this.incr2();
  17 + setTimeout(this.incr, 300); // executer 300 ms plus tard
  18 + // TODO: .bind(this)
  19 + setTimeout(this.incr2, 600); // executer 600 ms plus tard
  20 + },
  21 +};
  22 +
  23 +o.test();
js-examples/js-functions-this.js View file @ f2bf972
  1 +var o = {
  2 + i: 10000,
  3 +
  4 + test: function() {
  5 + console.log("START", this.constructor.name, this.i);
  6 +
  7 + const incr = function() {
  8 + this.i += 1;
  9 + console.log("FUNCT", this.constructor.name, this.i);
  10 + };
  11 + const incrArrow = () => {
  12 + this.i += 1;
  13 + console.log("ARROW", this.constructor.name, this.i);
  14 + };
  15 +
  16 + console.log();
  17 + incr();
  18 + incrArrow();
  19 + console.log();
  20 +
  21 + setTimeout(incr, 250); // this?!
  22 + setTimeout(incrArrow, 500); // ok
  23 +
  24 + setTimeout(incr.bind(this), 750); // ok
  25 + setTimeout(incrArrow.bind(this), 1000); // ok (useless)
  26 +
  27 + setTimeout(function() { incr(); }, 1250); // KO
  28 + setTimeout(() => { incr(); }, 1500); // KO
  29 + },
  30 +};
  31 +
  32 +o.test();
js-examples/js-functions-thisarrow-noparam-tentation-pb.js View file @ f2bf972
  1 +var o = {
  2 + démarrer: function() { // méthode
  3 +
  4 + this.i = 10000;
  5 + this.onAjouter1 = function() { // fonction traditionnelle
  6 + this.i += 1;
  7 + console.log(this.i);
  8 + };
  9 +
  10 + this.onAjouter2 = function() { // fonction avec bind
  11 + this.i += 1;
  12 + console.log(this.i);
  13 + }.bind(this);
  14 +
  15 + this.onAjouter3 = () => { // arrow function
  16 + this.i += 1;
  17 + console.log(this.i);
  18 + };
  19 +
  20 +
  21 + }
  22 +};
  23 +
  24 +// simuler des événements, de suite ou venant d'ailleurs
  25 +o.démarrer();
  26 +o.onAjouter1();
  27 +o.onAjouter2();
  28 +o.onAjouter3();
  29 +setTimeout( function(){ o.onAjouter1(); }, 50);
  30 +setTimeout( function(){ o.onAjouter2(); }, 100);
  31 +setTimeout( function(){ o.onAjouter3(); }, 150);
  32 +setTimeout( () => { o.onAjouter1(); }, 200);
  33 +setTimeout( () => { o.onAjouter2(); }, 250);
  34 +setTimeout( () => { o.onAjouter3(); }, 300);
  35 +setTimeout( o.onAjouter1, 1000);
  36 +setTimeout( o.onAjouter2, 1500);
  37 +setTimeout( o.onAjouter3, 2000);
js-examples/js-functions-thisarrow.js View file @ f2bf972
  1 +var o = {
  2 + démarrer: function() { // méthode
  3 +
  4 + this.i = 10000;
  5 + this.onAjouter1 = function(v) { // fonction traditionnelle
  6 + this.i += v;
  7 + console.log(this.i);
  8 + };
  9 +
  10 + this.onAjouter2 = function(v) { // fonction avec bind
  11 + this.i += v;
  12 + console.log(this.i);
  13 + }.bind(this);
  14 +
  15 + this.onAjouter3 = (v) => { // arrow function
  16 + this.i += v;
  17 + console.log(this.i);
  18 + };
  19 +
  20 +
  21 + }
  22 +};
  23 +
  24 +// simuler des événements, de suite ou venant d'ailleurs
  25 +o.démarrer();
  26 +o.onAjouter1(1);
  27 +o.onAjouter2(2);
  28 +o.onAjouter3(4);
  29 +setTimeout( function(){ o.onAjouter1(8); }, 500);
  30 +setTimeout( function(){ o.onAjouter2(16); }, 1000);
  31 +setTimeout( function(){ o.onAjouter3(32); }, 1500);
  32 +setTimeout( () => { o.onAjouter1(64); }, 2000);
  33 +setTimeout( () => { o.onAjouter2(128); }, 2500);
  34 +setTimeout( () => { o.onAjouter3(256); }, 3000);
media/frflag.svg View file @ f2bf972
  1 +<svg xmlns="http://www.w3.org/2000/svg" height="480" width="640" viewBox="0 0 640 480">
  2 + <g fill-rule="evenodd" stroke-width="1pt">
  3 + <path fill="#fff" d="M0 0h640v480H0z"/>
  4 + <path fill="#00267f" d="M0 0h213.337v480H0z"/>
  5 + <path fill="#f31830" d="M426.662 0H640v480H426.662z"/>
  6 + </g>
  7 +</svg>
raw/cours-10-13.zip View file @ f2bf972

No preview for this file type

raw/cours-10-20-api.zip View file @ f2bf972

No preview for this file type

raw/cours-10-20-js.zip View file @ f2bf972

No preview for this file type