Anthony Salembier @ Excilys - 2019

NGULAR

v7.2.12

Prérequis

  • NodeJS (LTS) v10.15.3
  • NPM v6.4.1
  • Angular CLI v7.3.8
  • (opt) Git
  • (opt) IDE Front : Visual Studio Code, Atom, Sublim Text, Webstorm (1 mois gratuit)

Présentation

Un peu d'histoire ...

-  Juin 2012 - AngularJS (Miško Hevery et Adam Abronsw puis Google)

-  Septembre 2016 - Angular 2

-  Mars 2017 - Angular 4

-  Novembre 2017 - Angular 5

-  Avril 2018 - Angular 6

-  Septembre/Octobre 2018  - Angular 7

Single Page Application

User Experience (UX)

Fluidité

Offline

Client <= Pages => Serveur

Client <= Ressources => Serveur

Typescript

Sur-ensemble de Javascript

Open source

Développé par Microsoft

Transpilé en Javascript

Typage statique

ECMAScript 6

Class, Interfaces

Survol d'Angular

Component tree

Component

Life Cycle Hooks

@Component({
    selector: string,
    templateUrl: string,
    styleUrls: string[],
    ...
})

Injectable

@Injectable({
    providedIn: ...
})

Directive

@Directive({
    selector: string,
    ...
})

Module

@NgModule({
    declarations: any[],
    imports: any[],
    exports: any[],
    providers: any[],
    ...
})

Overview

Data binding

Template binding {{ }}

<div>
    Hello {{ name }}
</div>

Dom events

<button (click)="doSomething()">
    Click me !
</button>

Liste des HTML DOM Events sans le "on" : 

click, dblclick, mousedown, keypress, change, resize, blur, focus, ...

https://www.w3schools.com/jsref/dom_obj_event.asp

*ngIf

<div *ngIf="expressionBooleenne">
    Hello
</div>

[hidden]

<div [hidden]="expressionBooleenne">
    Hello
</div>

*ngFor

<ul>
    <li *ngFor="let item of itemList">
        {{ item }}
    </li>
</ul>

Au travail !

On veut du clean code !!

(Indentation, code aéré, performant, lisible, …)

Excilys Cocktails

Génération "boilerplate" :

ng new first-app --style=scss

Excilys Cocktails

Lancement du serveur :

ng serve

Ou :

npm start

Excilys Cocktails

Un peu d'aide côté design : Angular Material

Installation :

npm install @angular/material @angular/cdk --save

Excilys Cocktails

Dans src/app :

ng generate module custom-material

Excilys Cocktails

Arborescence

package.json

Excilys Cocktails

Ajout d'un header

Dans src/app, créer le composant Header :

ng generate component header

Excilys Cocktails

Création du modèle

Composant Recipe :

ng generate component recipe

Excilys Cocktails

Création du modèle

recipe.model.ts

 

ingredient.model.ts

Excilys Cocktails

Création du modèle

import { Ingredient } from './ingredient.model';

export class Recipe {

    name: string;
    picture: string;
    description: string;
    ingredients: Ingredient[];
    instructions: string[];

}

Excilys Cocktails

Affichage des recettes

Paramètre d'entrée du composant :

@Input()
recipe: Recipe;

Excilys Cocktails

Affichage des recettes

Afficher la liste :

<app-recipe *ngFor="let recipe of recipes"
            [recipe]="recipe">
</app-recipe>

Excilys Cocktails

Affichage des recettes

Afficher / masquer les détails :

<button (click)="toggleExpand()">
    See more
</button>

Excilys Cocktails

Service RecipeService

Création du service :

ng generate service recipe --module=app

Excilys Cocktails

Service RecipeService

Refacto permettant de gérer l'asynchrone :

getRecipes(): Observable<Recipe[]> {
    return of(RECIPES);
}

Excilys Cocktails

Récupération des données de l'Observable

Dans un composant appelant le getRecipes() du service.

this.recipeService.getRecipes().subscribe(
    (result: Recipe[]) => {
        // Traiter le résultat
    },
    (error) => {
        // Traiter l'erreur
    }
);

Excilys Cocktails

Passage au HttpClient :

Prérequis (In Memory Web API) :

npm install angular-in-memory-web-api --save

Excilys Cocktails

Passage au HttpClient (In Memory Web API) :

Dans src/app : in-memory-data.service.ts

 

import { InMemoryDbService } from 'angular-in-memory-web-api';

export class InMemoryDataService implements InMemoryDbService {
    createDb() {
        const recipes = [ (Ajouter le modèle mocké ici) ]
        return {recipes};
    }
}

Excilys Cocktails

Passage au HttpClient (In Memory Web API) :

imports: [
    HttpClientInMemoryWebApiModule.forRoot(
        InMemoryDataService, { dataEncapsulation: false }
    )
],

AppModule :

Excilys Cocktails

Passage au HttpClient :

imports: [
        ...,
        HttpClientModule,
        ...
]

AppModule :

Excilys Cocktails

Passage au HttpClient :

private recipeUrl = 'api/recipes';

getRecipes(): Observable<Recipe[]> {
    return this.http.get<Recipe[]>(this.recipeUrl);
}

RecipeService :

Excilys Cocktails

Passage au HttpClient :

getRecipe(id: string): Observable<Recipe> {
    return this.http.get<Recipe>(`${ this.recipeUrl }/${ id }`);
}

RecipeService, ajout d'une requêt "by ID" :

Excilys Cocktails

Routing :

ng generate module app-routing --flat --module=app

AppRoutingModule

Excilys Cocktails

Routing :

const routes: Routes = [
    {
        path: 'recipes',
        component: RecipesComponent,
        pathMatch: 'full'
    },
    {
        path: '**',
        redirectTo: 'recipes',
        pathMatch: 'full'
    }
];

AppRoutingModule

Excilys Cocktails

Routing :

@NgModule({
    exports: [
        RouterModule
    ],
    imports: [
        RouterModule.forRoot(routes)
    ]
})

AppRoutingModule

Excilys Cocktails

Routing :

<router-outlet></router-outlet>

Point d'entrée des routes

Excilys Cocktails

Routing :

Refacto : Modularisation de Recipe

A vous de jouer

Excilys Cocktails

Nouvelle page : Détail d'une recette

  • Ajout d'une nouvelle page + composant : recipe-detail.component
  • Navigation par le router : /recipes/:id
  • Récupération d'une recette "byId"

TIPS :  

  • Créer une nouvelle route recipes/:id permet de variabiliser le param id
  • L'attribut routerLink="/recipes/{{ recipe.id }}" permet de naviguer vers une la nouvelle route
  • this.route.snapshot.paramMap.get('id') permet de récupérer le paramètre de la route à la création du composant (this.activatedRoute doit être injecté depuis le service Angular ActivatedRoute)

Excilys Cocktails

Nouvelle page : Formulaire d'ajout de recette

  • Ajout d'une nouvelle page de formulaire de création de recette
  • Ajout d'une nouvelle fonctionnalité POST dans le service

TIPS :  

  • Binding d'une donnée sur un élément HTML : [(ngModel)]="maVariable"

Excilys Cocktails

Suppression de recette

  • Bouton de suppression de recette
  • Ajout d'une nouvelle fonctionnalité DELETE dans le service

Overtime

Excilys Cocktails

Reactive Forms : Validation dynamique de formulaires

https://angular.io/guide/reactive-forms#add-a-formgroup

Excilys Cocktails

Pipes : Transformer les données

@Pipe({ 
    name: 'orderBy'
})
export class OrderByPipe implements PipeTransform {
    transform(param : InputType): OutputType {
        doSomething();
        return newValue;
    }
}

Excilys Cocktails

Tests unitaires !

Karma + Jasmine

Excilys Cocktails

Animations : Animer les composants

https://angular.io/guide/animations#setup

Les liens utiles

Made with Slides.com