A propos de l'auteur

Anna Prenzel a étudié l'informatique à l'Université des sciences appliquées de Zittau / Görlitz et a obtenu son doctorat au BTU Cottbus-Senftenberg.

Elle est …
Plus à propos
Anna

Cet article est dédié aux développeurs Angular qui souhaitent exploiter le concept de programmation réactive. Il s'agit d'un style de programmation qui, en termes simples, traite du traitement des flux de données asynchrones.

Aujourd'hui, je voudrais me concentrer sur les flux de données résultant des événements de clic sur l'interface utilisateur. Le traitement de ces flux de clics est particulièrement utile pour les applications avec une interaction utilisateur intensive où de nombreux événements doivent être traités. Je voudrais également vous présenter un peu plus RxJS; c'est une bibliothèque JavaScript qui peut être utilisée pour exprimer les routines de gestion des événements de manière compacte et concise dans un style réactif.

Que construisons-nous?

Les jeux d'apprentissage et les tests de connaissances sont populaires à la fois pour les jeunes et les plus âgés. Un exemple est le jeu de «jumelage de paires», où l'utilisateur doit trouver des paires apparentées dans un mélange d'images et / ou d'extraits de texte.

L'animation ci-dessous montre une version simple du jeu: L'utilisateur sélectionne deux éléments sur le côté gauche et droit du terrain de jeu l'un après l'autre, et dans n'importe quel ordre. Les paires correctement appariées sont déplacées vers une zone distincte du terrain de jeu, tandis que toute affectation incorrecte est immédiatement dissoute afin que l'utilisateur doive faire une nouvelle sélection.

Capture d'écran du jeu d'apprentissage «paires correspondantes»
Un aperçu du jeu que nous allons créer aujourd'hui

Dans ce tutoriel, nous allons construire un tel jeu d'apprentissage étape par étape. Dans la première partie, nous allons construire un composant angulaire qui ne fait que montrer le terrain de jeu. Notre objectif est que le composant puisse être configuré pour différents cas d'utilisation et groupes cibles – d'un quiz animal à un entraîneur de vocabulaire dans une application d'apprentissage des langues. À cette fin, Angular propose le concept de projection de contenu avec des modèles personnalisables, que nous utiliserons. Pour illustrer le principe, je construirai deux versions du jeu («game1» et «game2») avec des dispositions différentes.

Dans la deuxième partie du tutoriel, nous nous concentrerons sur la programmation réactive. Chaque fois qu'une paire est appariée, l'utilisateur doit obtenir une sorte de rétroaction de l'application; c'est cette gestion d'événements qui est réalisée à l'aide de la bibliothèque RxJS.

1. Construire un composant angulaire pour le jeu d'apprentissage

Comment créer le cadre de base

Commençons par créer un nouveau projet nommé "learning-app". Avec la CLI angulaire, vous pouvez le faire avec la commande nouvelle application d'apprentissage. Dans le fichier app.component.html, Je remplace le code source pré-généré comme suit:

Apprendre est amusant!

À l'étape suivante, le composant du jeu d'apprentissage est créé. Je l'ai nommé "match de jeu" et j'ai utilisé la commande ng générer un jeu de correspondance de composants. Cela créera un sous-dossier séparé pour le composant de jeu avec les fichiers HTML, CSS et Typescript requis.

Comme déjà mentionné, le jeu éducatif doit être configurable à différentes fins. Pour illustrer cela, je crée deux composants supplémentaires (game1 et game2) en utilisant la même commande. J'ajoute le composant de jeu en tant que composant enfant en remplaçant le code pré-généré dans le fichier game1.component.html ou game2.component.html avec la balise suivante:


Au début, je n'utilise que le composant game1. Afin de m'assurer que le jeu 1 s'affiche immédiatement après le démarrage de l'application, j'ajoute cette balise au app.component.html fichier:


Lors du démarrage de l'application avec ng serve --open, le navigateur affichera le message "Matching Game Works". (Il s'agit actuellement du seul contenu de matching-game.component.html.)

Maintenant, nous devons tester les données. dans le / app dossier, je crée un fichier nommé pair.ts où je définis la classe Paire:

paire de classe d'exportation {
  partie gauche: chaîne;
  partie droite: chaîne;
  id: nombre;
}

Un objet paire comprend deux textes associés (partie gauche et partie droite) et une pièce d'identité.

Le premier jeu est censé être un quiz sur les espèces dans lequel les espèces (par ex. chien) doivent être affectés à la classe d'animaux appropriée (c.-à-d. mammifère).

Dans le fichier animaux.ts, Je définis un tableau avec des données de test:

importer {Pair} depuis './pair';
export const ANIMALS: Pair[] = [
  { id: 1, leftpart: 'dog', rightpart: 'mammal'},
  { id: 2, leftpart: 'blickbird', rightpart: 'bird'},
  { id: 3, leftpart: 'spider', rightpart: 'insect'},
  { id: 4, leftpart: 'turtle', rightpart: 'reptile' },
  { id: 5, leftpart: 'guppy', rightpart: 'fish'},
];

Le composant game1 a besoin d'accéder à nos données de test. Ils sont stockés dans la propriété animaux. Le fichier game1.component.ts a maintenant le contenu suivant:

import {Component, OnInit} de '@ angular / core';
importez {ANIMALS} depuis '../animals';
@Composant({
  sélecteur: 'app-game1',
  templateUrl: './game1.component.html',
  styleUrls: ['./game1.component.css']
})
la classe d'exportation Game1Component implémente OnInit {
  animaux = ANIMAUX;
  constructeur () {}
  ngOnInit () {
  }
}

La première version du composant de jeu

Notre prochain objectif: le composant de jeu jeu de correspondance doit accepter les données de jeu du composant parent (par ex. game1) en entrée. L'entrée est un tableau d'objets «paire». L'interface utilisateur du jeu doit être initialisée avec les objets transmis lors du démarrage de l'application.

Capture d'écran du jeu d'apprentissage «paires correspondantes»

À cette fin, nous devons procéder comme suit:

  1. Ajouter la propriété paires au composant de jeu en utilisant le @Contribution décorateur.
  2. Ajouter les tableaux solvedPairs et unsolvedPairs comme propriétés privées supplémentaires du composant. (Il est nécessaire de faire la distinction entre les paires déjà «résolues» et «pas encore résolues».)
  3. Au démarrage de l'application (voir fonction ngOnInit) toutes les paires sont toujours «non résolues» et sont donc déplacées vers le tableau unsolvedPairs.
import {Component, OnInit, Input} de '@ angular / core';
importer {Pair} à partir de '../pair';
@Composant({
  sélecteur: 'app-matching-game',
  templateUrl: './matching-game.component.html',
  styleUrls: ['./matching-game.component.css']
})

la classe d'exportation MatchingGameComponent implémente OnInit {
  @Input () pairs: Pair[];
  privé résoluPaires: paire[] = [];
  paires non résolues privées: paire[] = [];
  constructeur () {}
  ngOnInit () {
    pour (soit i = 0; i <this.pairs.length; i ++) {
        this.unsolvedPairs.push (this.pairs[i]);
    }
  }
}

De plus, je définis le modèle HTML du jeu de correspondance composant. Il existe des conteneurs pour les paires non résolues et résolues. le ngIf La directive garantit que le conteneur respectif ne s'affiche que s'il existe au moins une paire non résolue ou résolue.

Dans le conteneur pour les paires non résolues (classe conteneur non résolu), tout d'abord la gauche (voir le cadre de gauche dans le GIF ci-dessus) et puis tous droite (voir le cadre de droite dans le GIF) les composants des paires sont répertoriés. (Je utilise le ngFor pour lister les paires.) Pour le moment, un simple bouton suffit comme modèle.

Avec l'expression modèle {{{pair.leftpart}} et {{{pair.rightpart}}}, les valeurs des propriétés partie gauche et partie droite des objets paire individuels sont interrogés lors de l'itération de la paire tableau. Ils sont utilisés comme étiquettes pour les boutons générés.

Les paires attribuées sont répertoriées dans le deuxième conteneur (classe conteneur résolu). Une barre verte (classe connecteur) indique qu'ils appartiennent ensemble.

Le code CSS correspondant du fichier matching-game.component.css peut être trouvé dans le code source au début de l'article.