Autour du codeDevelopper toujours mieux
Posté le

Débuter avec Angular2

Cet article a été écrit alors que Angular2 été en version alpha, beaucoup de choses ont changé depuis la sortie de la version stable j'ai donc fait un autre tutoriel sur Angular 2

Salut à vous et bienvenus dans cette initiation à Angular2. smile

Je dois avouer que AngularJS2 n'a plus grand chose avoir avec le 1, Plus de scope, plus de ng-app, un nouveau system d'injection de dépendance et un system de détection de changement beaucoup plus performant. Il existe une version Typescript et Dart dans ce tutoriel, les exemples seront en Typescript. Pour utiliser Angular2 il va donc falloire installer pas mal de chose dont le compilateur TypeScript.

On va donc commencer par installer node pour avoir npm.

$ wget http://nodejs.org/dist/v0.11.16/node-v0.11.16-linux-x64.tar.gz

$ tar -xaf node-v0.11.16-linux-x86.tar.gz

$ cd node-v0.11.16-linux-x86/bin/

$ export PATH=$PWD:$PATH

Une fois node installé, on va installer TypeScript et tsd qui va nous permettre de récupérer des fichier de définition.

$ ./npm install -g typescript@^1.5.0-beta

$ ./npm install -g tsd

L'installation est maintenant terminée, on vous pouvoir commencer à développer. Créer un répertoire qui contiendra votre application. On va ensuite installer dans ce répertoire les fichiers de description d'Angular2.

$ tsd query angular2 --action install

$ tsd query es6-promise --action install

$ tsd query rx --action install

$ tsd query rx-lite --action install

À la fin de cette étape, un fichier typing a été créé contenant ceci:

$ tree

.
+-- typings
    +-- angular2
    |   +-- angular2.d.ts
    +-- es6-promise
    |   +-- es6-promise.d.ts
    +-- rx
        +-- rx.d.ts
        +-- rx-lite.d.ts

On va commencer par écrire notre premier composant en créant un fichier "app.ts". Dans ce fichier, on va importer tout ce dont on a besoin pour ce premier exemple.

import {Component, View, bootstrap} from 'angular2/angular2';

Component qui va nous permettre d'indiquer quelle balise sera utiliser pour insérer notre composant dans une page HTML.View qui indique l'apparence de notre composant. C'est deux fonctions vont décorer une classe dans laquelle se trouvera la logique de notre composant, le contrôleur. Pour cette initiation à Angular2, le contrôleur sera vide, se sera seulement une classe en type script sans rien dedans.

class AppComponent {
}

La vue affichera juste un paragraphe avec marqué angular 2. Histoire de pas faire un truc trop bateau, on va quand même faire travailler un peu le moteur de template avec une addition.

@View({
    template: '<p>angular {{ 1 + 1 }}</p>'
})

Dans Angular, vous pouvez faire interpréter du code JS entre une paire de deux accolade. Notre composante pourra s'intégrer à une base html via la balise <my-app>

@Component({
    selector: 'my-app'
})

Pour que la composante soie chargée dans la page, la dernière étape est d'appeler la fonction bootstrap

bootstrap(MyAppComponent);

Voici à quoi doit ressembler votre fichier ts:

/// <reference path="typings/angular2/angular2.d.ts">

import {Component, View, bootstrap} from 'angular2/angular2';
@Component({
 selector: 'my-app'
})
@View({
template: '
<p>angular {{ 1 + 1 }}</p>
'
})
class AppComponent {
}

bootstrap(AppComponent);

Pour le compiler, lancé la ligne de commande qui suit :

$ tsc -m commonjs -t es5 --emitDecoratorMetadata app.ts

On va ensuite créer un index.html dans lequel importer notre composant. Entre les balises head, en plus des imports Angularjs2, on va également utiliser Systemjs pour utiliser la fonctionnalité ES6 de chargement de module.

<!DOCTYPE html>
<html>
  <head>
      <title>Angular 2 Quickstart</title>
      <script src="https://github.jspm.io/jmcriffey/bower-traceur-runtime@0.0.87/traceur-runtime.js"></script>
      <script src="https://jspm.io/system@0.16.js"></script>
      <script src="https://code.angularjs.org/2.0.0-alpha.26/angular2.dev.js"></script>
  </head>
  <body>
    <my-app></my-app>
    <script>
      System.import('app');
    </script>
  </body>
</html>

Reste plus qu'a lancer votre serveur dans un terminal à l'endroit où vous avez créé vos fichiers, lancez:

$ python -m SimpleHTTPServer 8080

Et rendez-vous dans votre navigateur à l'adresse 127.0.0.1:8080.

Séparer le template du code typescript

S'il y a beaucoup de code html à écrire, le template peut être externalisé dans un autre fichier en utilisant templateUrl à la place de template. Pour cet exemple, le code du template sera écrit dans le fichier 'app.html'. On va ajouter à notre classe AppComponent un attribut "team_number" de type entier. Pour l'afficher dans le template, on a jute à faire {{ team_number }}

Boucler sur une liste ...

On va ajouter un attribut team à notre classe AppComponent qui contiendra des noms dans un tableau de string. Dans notre template, on va utiliser la directive NgFor avant de pouvoir utiliser une directive, il faut l'importer :

import {NgFor} from 'angular2/angular2';

Puis l'ajouter à la liste des directives de notre vue.

@View({
    templateUrl: 'app.html',
    directives: [NgFor]
})

Une fois cette étape faite, on va pouvoir utiliser la directive ng-for dans le template de la sorte:

<ul>
  <li *ng-for="#member of team">{{member}}</li>
</ul>

Pour chaque élément dans l'attribut "team" du modèle, la balise li va être répétée avec la création d'une variable "member". La variable "member" est ensuite utilisée entre les balises grâce à la syntaxe {{member}}.

Utiliser une structure conditionnelle ...

La directive est NgIf. Comme pour l'utilisation de NgFor, il va falloir l'importer et la déclarer dans la liste des directives de la vue.

Voici comment on peut l'utiliser dans le template:

<p *ng-if="team.length == 0">Il n'y a pas de membre dans l'équipe</p>

Si la longueur de team est de 0 alors la balise est sont contenue sont affichée.

/// <reference path="typings/angular2/angular2.d.ts" />

import {Component, View, bootstrap, NgFor, NgIf} from 'angular2/angular2';
@Component({
    selector: 'my-app'
})
@View({
    templateUrl: 'app.html',
    directives: [NgFor, NgIf]
})
class AppComponent {
    team: Array<string>;
    team_number: number;

    constructor() {
        this.team_number = 1;
        this.team = ['Daniel Jackson', "Jack O'neal"];
    }
}

bootstrap(AppComponent);

<p>SG{{team_number}}</p>
<ul>
  <p *ng-if="team.length == 0">Il n'y a pas de membre dans l'équipe</p>
  <li *ng-for="#member of team">{{member}}</li>
</ul>

Les entrées de l'utilisateur

On va ajouter une méthode addTeamMember à notre classe AppComponent. Elle prendra en paramètre le nouveau membre de l'équipe. Dans le template, on peut créer une variable qui sera lié dynamiquement à une balise input en ajoutant un nom de la variable précédé d'un # comme attribut à la balise.

<input #new_member (keyup)>

On indique entre parenthèses sur quel événement cette variable est modifiée. Pour utiliser la valeur de cette variable dans notre template on utilisera

{{new_member.value}}

On va ensuite créer un bouton qui appellera la méthode addTeamMemberpour ajouter le nouveau membre à l'équipe. Pour un effet sympa, on va faire en sorte que le membre apparaisse dans l'équipe dés que l'on commence à saisir son nom en créant une balise li à la volée en fonction de si la variable new_member est vide ou pas.

/// <reference path="typings/angular2/angular2.d.ts" />

import {Component, View, bootstrap, NgFor, NgIf} from 'angular2/angular2';
@Component({
    selector: 'my-app'
})
@View({
    templateUrl: 'app.html',
    directives: [NgFor, NgIf]
})
class AppComponent {
    team: Array<string>;
    team_number: number;

    constructor() {
        this.team_number = 1;
        this.team = ['Daniel Jackson', "Jack O'neal"];
    }

    addTeamMember(member: string) {
        this.team.push(member);
    }
}

bootstrap(AppComponent);

<p>SG{{team_number}}</p>

<input #new_member (keyup)>
<button (click)="addTeamMember(new_member.value)">Add Member</button>

<p *ng-if="team.length == 0">Il n'y a pas de membre dans l'équipe</p>
<ul>
  <li *ng-for="#member of team">{{member}}</li>
  <li *ng-if="new_member.value">{{new_member.value}}</li>
</ul>

C'est pratique, mais, il serait sympa de remettre le champ à vide après avoir ajouté un nouveau membre. Pour faire cela, on va utiliser un objet Control. Cet objet se met à jour lorsque la valeur d'un champ est changée et change la valeur de ce champ lorsqu'il est modifié via ça méthode updateValue. On va donc créer un nouvel attribut dans notre classe de type Control que l'on appellera "new_member". Afin d'utiliser control il faut l'importer ainsi que formDirectives. Puis ajouter dans les directives de la vue uniquement formDirectives.

team: Array<string>;
team_number: number;
new_member: Control;

constructor() {
    this.team_number = 1;
    this.team = ['Daniel Jackson', "Jack O'neal"];
    this.new_member = new Control('');
}

On va modifier la méthode addTeamMember comme ceci:

addTeamMember() {
    this.team.push(this.new_member.value);
       this.new_member.updateValue('');
}

Dans notre template, on va utiliser la dirrective [ng-form-control] et lui indiquer à quel objet Control on souhaite la liéer. Voici à quoi ressemble notre template et notre fichier ts après les modifications

/// <reference path="typings/angular2/angular2.d.ts" />

import {Component, View, bootstrap, NgFor, NgIf, formDirectives, Control} from 'angular2/angular2';
@Component({
    selector: 'my-app'
})
@View({
    templateUrl: 'app.html',
    directives: [NgFor, NgIf, formDirectives]
})
class AppComponent {
    team: Array<string>;
    team_number: number;
    new_member: Control;

    constructor() {
        this.team_number = 1;
        this.team = ['Daniel Jackson', "Jack O'neal"];
        this.new_member = new Control('');
    }

    addTeamMember() {
        this.team.push(this.new_member.value);
        this.new_member.updateValue('');
    }
}

bootstrap(AppComponent);

<p>SG{{team_number}}</p>

<input type='text' [ng-form-control]="new_member">
<button (click)="addTeamMember()">Add Member</button>

<p *ng-if="team.length == 0">Il n'y a pas de membre dans l'équipe</p>
<ul>
  <li *ng-for="#member of team">{{member}}</li>
  <li *ng-if="new_member.value">{{new_member.value}}</li>
</ul>

Voilou j'espère que ça vous a donné envie d'essayer, il y aura d'autre article sur ce sujet peut-être que d'ici là toute aura changé, car il ne faut pas l'oublier, Angular2 n'est pour le moment qu'en version alpha, alors en attendant la béta, à vos IDE et bon code laughing