Chargement...

ANGULAR-TUTO.COM

04 Angular2 Components

04 Les components dans Angular2

Bonjour,
Angular2 se base essentiellement sur les composants ou bien en anglais “Components”. Le but de ce tutorial est de savoir comment créer un component.
Quels sont les propriétés utilisées pour définir un component ?
Aussi on va traduire tout ça dans un exemple concret.

Comparaison Angular2:Component // AngularJS:Directive

Lorsque AngularJS apparu dans l’année 2009, il a apporté avec lui une notion très importante dans le monde de la programmation. C’est la notion des web components. L'intérêt des web components est l’encapsulation du métier et du html dans une seule entité.

  • Après avoir remarqué la puissance de cette encapsulation, Google a décidé de baser le nouveau framework (Angular2) sur les components.
  • Finalement les components dans Angular2 sont des directives qui sont toujours associé à une template HTML spécifié.
  • La connection entre le code et la template HTML dans les components du Angular2 permet de résoudre des problèmes et des notions très nécessaire dans AngularJS comme la notion du “$scope”
  • Les components dans Angular2 ont un cycle de vie qui peut être personnaliser. En fait les méthodes ngOnInit() et ngOnDestroy() peuvent être surchargées et ça permet de personnaliser très simplement le comportement des composants. Tout ça vous donne un contrôle total sur votre component. (J’adore ça)
  • Component de type Premier niveau

    Dans Angular2 toujours, il y a un composant du premier niveau. Les autres components seront liés à ce component du premier niveau.

    But à atteindre

    Le but de ce tutorial est de créer une première application Angular2 qui permet de lister les hotels de Paris.
    Nous allons créer:

  • Un component principal "appcomponent"
  • Un deuxième component "hotelcomponent" qui sera appélé par le premier component
  • Un service qui joue le role d'une source de données
  • le resultat doit etre comme suivant:
    Structure de notre application

    Le dossier app souligné en rouge dans la figure precedente est le dossier de notre apllication.

  • app.ts est le fichier qui contient le component du premier niveau de notre application
  • hotel.ts est le fichier qui contient un deuxième component utilisé dans l'application
  • hotel.service.ts contient le service qui stocke la liste des hotels de Paris
  • Component Premier niveau "AppComponent"

    Le fichier ap.component.ts est le component principale de notre application.
    Merci de lire attentivement les commentaires de chaque ligne de code Parmi les chose à mettre en considération c'est l'utilisation du décoratuer @component

     
        //appcomponent.ts
     // importer la classe Component à partir de la bibliothèque @angular/core 
    import { Component } from '@angular/core';
    //importer la methode bootstrap  à partir @angular/platform-browser-dynamic ppour charger le web app
    import { bootstrap } from '@angular/platform-browser-dynamic'; 
    
    /** Importer les autres composants necessaires */ 
    import { hotelComponent } from 'app/hotel.component';
    import { hotelService } fromt 'app/hotel.service';
    //@Component est une annotation qui permet de definir notre component 
    @Component({
      // permet de créer la balise <my-app></my-app>
      selector: 'my-app',
      //directives permet de lister les autres components qui seront appélés par Ce component dupremier niveau
      directives: [hotelComponent],
      // les classes css utilisées dans notre component
      styles: [`
      h1 {
        color:#545454;
        background:#a3e27c;
        padding:15px;
        box-shadow:2px 2px 2px 0 rgba(0, 0, 0, 0.3);
      }
      `]
      // la template HTML du notre component
      template: `
      <div>
      <h1>Le component Principale:<u> {{componentName}}</u> fait appel au 2eme component (hotelcomponent).</h1>
      <my-hotels></my-hotels>
      </div>
      `
    })
    // exporter notre component à l exterieur ainsi il peut etre utilisé par d autre components
    export class AppComponent {
      componentName : string = 'AppComponent';
    }
    bootstrap(AppComponent)
    
        
                                
    Component deuxième niveau "HotelComponent"

    Le component principal appcomponent va faire appel à un ou plusieurs autres components secondaires. Dans notre cas il invoque le component hotelcomponent.

     
    //hotelcomponent.ts
    import { Component } from '@angular/core';
    //importer le service hotelService (voir en bas de la page)
    import { hotelService } from 'app/hotel.service';
    
    @Component({
      selector: 'my-hotels',
      // providers permet de lister les services utilisés dans ce component 
      providers : [hotelService],
      styles: [`
      div { 
         background-color:#EFEFEF;
         margin-bottom:15px;
         padding:15px;
         border:1px solid #DDD;
         box-shadow:2px 2px 2px 0 rgba(0, 0, 0, 0.3);
        border-radius:3px;
      }
      h2 { 
        text-align: center;
      }
      `]
      template: `
      <!-- -->
      <h2>Les hotels de Paris: {{componentName}} </h2>
      <div *ngFor="let f of hotels">
       <b< Nom de l'hotel :</b> {{f.name}} 
       <br/>
        <b>Avis sur l'hotel:</b> {{f.description}} 
      </div>
      `
    })
    // exposer le component à l exterieur pour qu il sera appélé par s'autres components'
    export class hotelComponent {
      componentName: string = 'hotelComponent';
      //Dans le constructeur: Dependency injection (Permet de faire appel à une instance du service sans utiliser le mot clé new)
        constructor(_hotelService: hotelService) {
            //gethotels() est une methode dans notre service qui retourne la liste des hotels
        this.hotels = _hotelService.gethotels();
      }
    }
            
            
    On remarque l'utilisation de la directive *ngFor qui permet de boucler sur l'ensemble " hotels". " hotels" est une variable à remplir en utilisant le service.
    Service "hotel.service.ts"

    Le service hotelService dans le fichier hotel.service.ts va exposer les données qui seront utilisées par le hotelComponent.
    L'utilisation de l'annotation @Injectable permet d'informer Angular2 que la classe (Dans notre cas le service hotelService) peut etre utilisée par la technique Dependency Injection.

     
            //hotel.service.ts
    //On commence par importer la classe Injectable
    import { Injectable } from '@angular/core';
    @Injectable()
    export class hotelService {
      hotels:Array;
    
      constructor() {
        this.hotels = [
        { description: 'Super Accueil / Super endroit', name: 'Hôtel Les Almadies' },
        { description: 'aux petits soins', name: 'La Réserve Paris - Hotel and Spa' },
        { description: 'Bien situé et très agréable', name: 'Hôtel Monge' },
        { description: 'Un acceuil exceptionnel', name: 'Villa Lara' },
        { description: 'Séjour fabuleux', name: 'La Maison dAix' },
        { description: 'La désirade d y revenir', name: 'Hotel La Désirade - Relais du Silence' },
        { description: 'Un vrai Hotel de charme !', name: 'LHOTEL PARTICULIER BEZIERS' },
        { description: 'Un bijoux au centre de Paris', name: 'Hotel La Tamise - Esprit de France' },
        { description: 'Un excellent Hotel ', name: 'Hotel Saint-Marc' }
        ];
      }
    // gethotels() retournera la liste des hotels 
      gethotels() {
        return this.hotels;
      }
    }
    
        
    Index.HTML

    Dans le fichier Index.html on va faire appel à notre nouvelle balise Angular2
    <my-app>Chargement...</my-app>

     
    <html>
      <head>
        <title>HOTLES DE PARIS</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="styles.css">
        <!-- 1. Charger les bibliotheques --> 
        <script src="node_modules/core-js/client/shim.min.js"></script>
        <script src="node_modules/zone.js/dist/zone.js"></script>
        <script src="node_modules/reflect-metadata/Reflect.js"></script>
        <script src="node_modules/systemjs/dist/system.src.js"></script>
        <!-- 2. Configurer SystemJS -->
        <script src="systemjs.config.js"></script>
        <script>
          System.import('app').catch(function(err){ console.error(err); });
        </script>
      </head>
      <!-- 3. Charger notre application nommée app -->
      <body>
        <my-app>Chargement...</my-app>
      </body>
    </html>
    
       
    Fichiers de configuration

    Comme dans chaque exemple Angular2 on a besoin de mettre en place quelques fichiers de configuration comme package.json ...

     
    //package.json
    {
      "name": "angular-quickstart",
      "version": "1.0.0",
      "scripts": {
        "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
        "lite": "lite-server",
        "tsc": "tsc",
        "tsc:w": "tsc -w"
      },
      "licenses": [
        {
          "type": "MIT",
          "url": "https://github.com/angular/angular.io/blob/master/LICENSE"
        }
      ],
      "dependencies": {
        "@angular/common": "~2.2.0",
        "@angular/compiler": "~2.2.0",
        "@angular/core": "~2.2.0",
        "@angular/forms": "~2.2.0",
        "@angular/http": "~2.2.0",
        "@angular/platform-browser": "~2.2.0",
        "@angular/platform-browser-dynamic": "~2.2.0",
        "@angular/router": "~3.2.0",
        "@angular/upgrade": "~2.2.0",
        "angular-in-memory-web-api": "~0.1.15",
        "core-js": "^2.4.1",
        "reflect-metadata": "^0.1.8",
        "rxjs": "5.0.0-beta.12",
        "systemjs": "0.19.39",
        "zone.js": "^0.6.25"
      },
      "devDependencies": {
        "@types/core-js": "^0.9.34",
        "@types/node": "^6.0.45",
        "concurrently": "^3.0.0",
        "lite-server": "^2.2.2",
        "typescript": "^2.0.3"
      }
    }
    
       
     
    //System.config.js
    /**
     * vous pouvez modifier selon vos besoin
     */
    (function (global) {
      System.config({
        paths: {
          // le lien vers le fichiers de configuration npm
          'npm:': 'node_modules/'
        },
        // map tells the System loader where to look for things
        map: {
          // notre applicaton est dans le dossier app
          app: 'app',
          // les module demandés par angular 
          '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
          '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
          '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
          '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
          '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
          '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
          '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
          '@angular/router/upgrade': 'npm:@angular/router/bundles/router-upgrade.umd.js',
          '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
          '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
          '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',
          
           'rxjs':                      'npm:rxjs',
          'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
        },
        // packages configure le chargement si les fichiers n ont pas la bonne extension
        packages: {
          app: {
            main: './main.js',
            defaultExtension: 'js'
          },
          rxjs: {
            defaultExtension: 'js'
          }
        }
      });
    })(this);
          
    
     
    //tsconfig.json
    {
      "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": false,
        "noImplicitAny": false
      }
    }
    

    Vous pouvez télécharger le code source de cette seance à partir de ce lien