Please wait, while our marmots are preparing the hot chocolate…
# @chunk: chunks/title.md # Questions ?
Commentaires ? {no-print} # @chunk: chunks/objectives.md ## Programmation Web Avancée {var-cours-n} : Plan {#plan overview} - Javascript {rappeljs} - Vue : les bases {vue} - Vue : composants {vuecomp} - Principes REST {rest} - Serveur REST en Spring {springrest} - Client REST JSON en Vue {restjs} # @copy:#plan # @copy:#plan: %+class:inred: .rappeljs # slides précédents ## Fonctions JS {libyli} - Fonction nommée « classique » en JavaScript ```javascript function toto(a,b) { return a+b; } alert(toto(1,3)); {dense slide} ``` - Fonction JavaScript : objet de première classe ```javascript var f = function(a) { return a*a; } alert(f(2)); var squares = [1,2,3].map(f); {dense slide firstorder} ``` - @anim: .firstorder>span:nth-of-type(4) | .firstorder>span:nth-of-type(5) - Fonction anonyme ```javascript var squares = [1,2,3].map(function(a) { return a*a; }); setTimeout(function() { alert("Hello"); }, 3000); {dense slide anonymous} ``` - @anim: .anonymous>span:nth-of-type(5), .anonymous>span:nth-of-type(6) ## Objets et Classes JS {libyli} - JS n'est pas un langage orienté classe (Java) - JS est un langage à prototype - Très dynamique - Attention à `this` (≠ Java) - un objet « contexte » - pas nécessairement d'un type donné (comme la classe) - Plus flexible que les langages à classes - Le mot clé `class` arrive en ES6 ;-( ## ES6 (ES2015) {libyli} - Syntaxe : class - `constructor()`, `super()` - `get`, `set` - Syntaxes - Modifieurs et portées de variables : const, var, val, let - *Arrow Functions* et gestion du `this` - Interpolation de string `̀ Hello ${name}̀ ` (backticks) - Propriétés : raccourcis, méthodes, prop. construire (`[ «» ] : «»`) - Construction et déconstruction pour listes et objets (avec valeur par défaut et y compris en param) - *Rest* et *Spread* avec `...` (y compris en paramètre, syntactic sugar pour `arguments`) - Paramètres par défaut `a=2` - Autres : modules, generator - etc. ## Gestion du `this` et *Arrow Functions* (ES6) {libyli} - Attention à `this` (≠ Java) - un objet « contexte » variable - pas nécessairement d'un type donné (comme la classe) ```javascript var o = { i: 10000, test: function() { this.incr = function() { this.i += 1; console.log(this.i); }; this.incr2 = () => { this.i += 1; console.log(this.i); }; this.incr(); this.incr2(); setTimeout(this.incr, 300); // executer 300 ms plus tard // TODO: .bind(this) setTimeout(this.incr2, 600); // executer 600 ms plus tard }, }; o.test(); {slide dense} ``` # @copy:#plan: %+class:inred: .vue # Sans et avec Vue :
des champs synchronisés ## Ce qu'on a utilisé - Javascript - `Array.from()`, `document.querySelectorAll`, `.forEach` - `Math.random()` - `.oninput`, `.tagName`, `.value`, `.textContent` - CSS (`background`, `border`, `padding`) ## Vue / Vuex - Vue - framework léger pour applications interactives coté client - similarité avec Angular, React, Ember, ... - approche composant avec bindings - https://vuejs.org/v2/guide/ - https://fr.vuejs.org/v2/guide/index.html - Vuex - https://vuex.vuejs.org/en/ - https://vuex.vuejs.org/fr/ # Sans et avec Vue :
des champs synchronisés ## Vue : Principes {libyli} - Données observables, rendu automatiquement à jour - Template HTML+CSS - avec des moustaches `{{ ... }}{}` (n'importe quelle expression ecmascript) - avec des directives *vue*, éléments avec des attributs `v-...` - accès automatique au *ViewModel* - Objet javascript de type `Vue` ```javascript var vm = new Vue({ el: ..., // selecteur CSS de l'élément à traiter data: { // objet contenant l'état / les données / le ViewModel ... }, methods: { // les actions / le comportement ... }, computed: { // des fonctions, chacune renvoie une propriété calculée ... // possibilité de {get: ..., set: ...} pour un mutateur calculé }, watch: { // listener quand une des propriétés de data change ... } }); {slide dense} ``` ## Vue : Liaison unidirectionnelle {libyli} - Comme les moustaches mais pour des attributs - Utlisation de `v-bind:...` ou `:...` - Cas des attributs booléen (présent ou non dans le DOM), e.g. `:disabled="ind==0"` ## Vue : Liaison avec des formulaires {libyli} - Pour les éléments éditables (input, select ou textarea) - Liaison bidirectionnelle (de la propriété `value` de ces éléments) - Attribut `v-model="..."` - Valeur : nom de la propriété de l'état - Modificateurs en suffixe `.lazy`, `.number`, `.trim` ## Vue : Gestion des événements {libyli} - Événements avec attributs `v-on:...` (ou `@...`) - Valeur de l'attribut - nom de la méthode - ou, code à exécuter - Modificateurs en suffixe - gestion de l'événement : `.stop`, `.prevent`, `.once`, ... - pour les touches et/ou click souris : `.shift`, `.ctrl`, `.exact`, ..., - pour spécifier une touche : `.enter`, `.up`, `.space`, `.65`, ..., - pour spécifier un bouton de la souris : `.left`, `.middle`, `.right` ``` click ou ctrl+mouvement click ou ctrl+mouvement {slide denser} ``` ## Vue : conditions et itérations {libyli} - Affichage conditionnel avec `v-if="..."` - expression booléene décidant du rendu ou non de l'élément - NB: l'élément n'est alors pas dans le DOM - Affichage en boucle (comme Thymeleaf) avec `v-for="vvv in lll"` - nom de variable arbitraire - possibilité d'avoir auss l'indice avec `(vvv, iii) in lll` ## Vue : Autre - Variables de contexte selon les cas: `$index` (boucles), `$event` (listener), ... # @copy:#plan: %+class:inred: .vuecomp ## Vue : Composants {libyli} - But - encapsuler un rendu et/ou comportement - créer ses propres éléments, par ex, `〈pwa year="2017"〉Rocks〈/pwa〉{dense}` - Fonction `Vue.component` - `props`: liste des attributs attendus - `template`: template HTML - attention, `data` doit être une fonction (si présent) ``` Vue.component('nom-du-tag', { props: ['msg'], template: '
{{ msg }}
', data: function () { return { ... } }, }); {slide} ``` - Utilisation ``` {slide} ``` ## Vue : Émettre des événements depuis un composant {libyli} - Dans le composant - utilisation de la fonction `$emit` - par ex : `$emit('truc')` - Dans le parent, ecoute classique - par ex : `v-on:truc` ou `@truc` - Possibilité d'utiliser `v-model` (bidirectionnel) - avoir une prop `value` - émettre des événements `input` (`this.$emit('input', v)`) ## Vue : à voir - composants dans un fichier `.vue` (pas de `template:'....'`) - transition / animations - packaging - vue cli : ligne de commande - vuex : gestion d'état centralisé - routeur : url, bookmarking, deep linking - directives perso # @copy:#plan: %+class:inred: .rest # Principes REST : *Representational State Transfer* ## *Representational State Transfer* {libyli} - Thèse de Roy T. Fielding (et [fr]) - Un style d'architecture - un ensemble de ressources - des liens entre ces ressources - comme une bonne application Web - Hypermedia as the engine of application state (HATEOAS) {slide} // important : le client choisi ce qu'il fait, le serveur guide - Propriété et objectifs - performance et passage à l'échelle // cacheable - simplicité et évolutivité - Principes {libyli} - client-serveur, *stateless* (sans état), couches (cache, sécurité, ...) // ne sait pas si on parle au serveur directement - ressources auto-décrites avec identifiant et métadonnées, HATEOAS - Résumé en Français ## *RESTful HTTP APIs* : REST sur HTTP {libyli} // RESTful (adjectif de REST) - Ressource : identifiant et représentation - URI (*Unique Resource Identifier*), `https://github.com/apache/spark {dense}` - métadonnées, ex : `Content-Type: text/html{dense}`, `Content-Encoding: gzip{dense}` - données, ex : HTML gzippé -   {no} - NB : pas de verbes ou actions dans les URI // capital ! - ok : `https://github.com/repositories` - ko : `https://github.com/createNewRepo?name=pwa` - Protocole *stateless* : HTTP avec méthodes HTTP {libyli} - GET : sûre (sans effets de bords) - récupère la représentation d'une ressource - liste le contenu d'une collection - DELETE : idempotente (même résultat si appliqué plusieurs fois) - supprime une ressource existante - supprime une collection - PUT : idempotente - remplace ou met à jour une ressource - remplace ou met à jour une collection - POST : - crée une nouvelle entrée dans une collection # @copy:#plan: %+class:inred: .springrest # (Tutoriel Spring+REST+React) ## Création d'un Modèle REST en Spring {libyli} - {no} - But : partager un modèle JPA en REST, au format JSON - Étapes - modèle : entités JPA - service : repository `JpaRepository` (ou `CrudRepository`) - `spring-data-rest-webmvc` (dépendance maven) - ou à la main avec `@RestController`, `@Valid`, `RequestMethod.*` - (configuration : `spring.data.rest.base-path=/api`) - si client est à une autre url : *Cross-origin resource sharing* (CORS) - Test simplifiés ``` curl -X GET http://localhost:8080/api/hotels curl -X POST http://localhost:8080/api/hotels -H "Content-Type: application/json" -d '{"name":"ibis", "nrooms":444}' curl -X GET http://localhost:8080/api/hotels curl -X GET http://localhost:8080/api/hotels/ibis curl -X DELETE http://localhost:8080/api/hotels/ibis curl -X GET http://localhost:8080/api/hotels {denser slide} ``` - {no} - Let's do it ! (hotels) - (plugin JSONView + cfg content `application/hal+json`) # @copy:#plan: %+class:inred: .restjs # à venir

/ will be replaced by the authorwill be replaced by the title