Maison > interface Web > js tutoriel > Angular et RXJS: ajout d'une API REST

Angular et RXJS: ajout d'une API REST

William Shakespeare
Libérer: 2025-02-15 13:25:11
original
918 Les gens l'ont consulté

Angular et RXJS: ajout d'une API REST

Cet article est la partie 3 du tutoriel Angular 2 SitePoint sur la façon de créer une application crud avec la CLI angulaire. Dans cet article, nous mettrons à jour notre application pour communiquer avec une API REST Back End.

Vous préférez apprendre Angular en utilisant un cours vidéo étape par étape? Consultez Apprenez Angular 5 sur SitePoint Premium.

Dans la première partie, nous avons appris à obtenir notre application TODO en cours d'exécution et à la déployer sur les pages GitHub. Cela a très bien fonctionné mais, malheureusement, toute l'application a été entassée en un seul composant.

Dans la deuxième partie, nous avons examiné une architecture de composants plus modulaire et appris à briser ce seul composant en un arbre structuré de composants plus petits qui sont plus faciles à comprendre, à réutiliser et à maintenir.

  1. Partie 0 - Le guide de référence CLI angulaire ultime
  2. Partie 1 - Obtenir notre première version de l'application TODO en cours d'exécution
  3. Partie 2 - Création de composants distincts pour afficher une liste de todos et un seul TODO
  4. Partie 3 - Mettez à jour le service TODO pour communiquer avec une API REST Back End
  5. Partie 4 - Utilisez un routeur angulaire pour résoudre les données
  6. Partie 5 - Ajouter l'authentification pour protéger le contenu privé
  7. Partie 6 - Comment mettre à jour les projets angulaires vers la dernière version.

Vous n'avez pas besoin d'avoir suivi les parties un et deux de ce tutoriel pour trois pour avoir un sens. Vous pouvez simplement récupérer une copie de notre dépôt, vérifier le code de la deuxième partie et l'utiliser comme point de départ. Ceci est expliqué plus en détail ci-dessous.

Angular et RXJS: ajout d'une API REST

Les plats clés

  • Utilisez HTTPClient d'Angular avec RXJS pour gérer efficacement les demandes HTTP asynchrones lors de la communication avec une API REST.
  • Stocker les URL de l'API dans les variables d'environnement pour basculer de manière transparente entre les environnements de développement et de production sans modifier le code.
  • Implémentez des méthodes d'applications telles que GetAllTodos, CreateTodo et DeleTeTodo pour interagir avec l'API REST en utilisant des méthodes HTTP appropriées.
  • Transition Tododataservice du stockage en mémoire pour tirer parti de l'apisservice pour les opérations de données, en s'adaptant aux modèles asynchrones avec observables.
  • Mettez à jour AppComponent pour gérer les observables renvoyés par apicevice, garantissant que les composants réagissent aux changements de données de manière asynchrone.
  • Introduire APIMOCKSERVICE pour les tests unitaires, permettant la simulation de l'APISERVICE sans les demandes HTTP réelles, assurant la fiabilité et l'indépendance des tests.
  • Configurer les configurations de tests d'applications angulaires pour inclure les services nécessaires tels que l'apisservice et gérer efficacement les scénarios de test asynchrones.

un récapitulatif rapide

Voici à quoi ressemblait notre architecture d'application à la fin de la partie 2:

Angular et RXJS: ajout d'une API REST

Actuellement, le TododataService stocke toutes les données en mémoire. Dans ce troisième article, nous mettrons à jour notre application pour communiquer avec une API REST à la place.

nous allons:

  • Créez une API de repos simulée
  • Stockez l'URL de l'API comme variable d'environnement
  • Créez un apice pour communiquer avec l'API REST Back End
  • Mettez à jour le TododataService pour utiliser le nouvel apivice
  • Mettez à jour l'approche pour gérer les appels API asynchrones
  • Créez un APIMOCKSERVICE pour éviter de vrais appels HTTP lors de l'exécution des tests unitaires.

Angular et RXJS: ajout d'une API REST

À la fin de cet article, vous comprendrez:

  • comment vous pouvez utiliser les variables d'environnement pour stocker les paramètres d'application
  • comment vous pouvez utiliser le client HTTP angulaire pour effectuer des demandes HTTP
  • comment vous pouvez gérer les observables qui sont renvoyés par le client HTTP angulaire
  • Comment vous pouvez moquer les appels HTTP pour éviter de faire une véritable demande HTTP lors de l'exécution de tests unitaires.

Alors, commençons!

opérationnel

Assurez-vous que la dernière version de la CLI angulaire installée. Si vous ne le faites pas, vous pouvez l'installer avec la commande suivante:

<span>npm install -g @angular/cli@latest
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Si vous avez besoin de supprimer une version précédente de la CLI angulaire, vous pouvez:

npm uninstall -g @angular/cli angular-cli
npm cache clean
<span>npm install -g @angular/cli@latest
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Après cela, vous aurez besoin d'une copie du code de la deuxième partie. Ceci est disponible sur github. Chaque article de cette série a une balise correspondante dans le référentiel afin que vous puissiez basculer entre les différents états de l'application.

Le code avec lequel nous avons terminé dans la deuxième partie et que nous commençons dans cet article est tagué en tant que partie-2. Le code avec lequel nous terminons cet article est tagué dans la partie 3.

Vous pouvez penser à des balises comme un alias à un ID de validation spécifique. Vous pouvez basculer entre eux à l'aide de la caisse GIT. Vous pouvez en savoir plus ici.

Donc, pour se mettre en service (la dernière version de la CLI angulaire installée), nous ferions ceci:

<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git
</span><span>cd angular-todo-app
</span><span>git checkout part-2
</span><span>npm install
</span>ng serve
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Visitez ensuite http: // localhost: 4200 /. Si tout va bien, vous devriez voir l'application Todo de travail.

Configuration d'une API REST Back End

utilisons JSON-Server pour configurer rapidement une simulation arrière.

De la racine de l'application, exécutez:

<span>npm install json-server --save
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ensuite, dans le répertoire racine de notre application, créez un fichier appelé db.json avec le contenu suivant:

<span>{
</span>  <span>"todos": [
</span>    <span>{
</span>      <span>"id": 1,
</span>      <span>"title": "Read SitePoint article",
</span>      <span>"complete": false
</span>    <span>},
</span>    <span>{
</span>      <span>"id": 2,
</span>      <span>"title": "Clean inbox",
</span>      <span>"complete": false
</span>    <span>},
</span>    <span>{
</span>      <span>"id": 3,
</span>      <span>"title": "Make restaurant reservation",
</span>      <span>"complete": false
</span>    <span>}
</span>  <span>]
</span><span>}
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Enfin, ajoutez un script à package.json pour démarrer notre back-end:

<span>"scripts": {
</span>  <span>...
</span>  <span>"json-server": "json-server --watch db.json"
</span><span>}
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Nous pouvons maintenant lancer notre API REST Back End en utilisant:

<span>npm run json-server
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cela devrait afficher ce qui suit:

  <span>\{^_^}/ hi!
</span>
  Loading db.json
  Done

  Resources
  http://localhost:3000/todos

  Home
  http://localhost:3000
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

c'est tout! Nous avons maintenant une API REST à l'écoute du port 3000.

Pour vérifier que votre back-end est en cours d'exécution comme prévu, vous pouvez naviguer sur votre navigateur vers http: // localhost: 3000.

Les points de terminaison suivants sont pris en charge:

  • get / todos: obtenez tous les todos existants
  • get / todos /: id: obtenez un todo existant
  • post / todos: créez un nouveau todo
  • put / todos /: id: mettez à jour un todo existant
  • delete / todos /: id: supprimer un todo existant

Donc, si vous naviguez sur votre navigateur vers http: // localhost: 3000 / todos, vous devriez voir une réponse JSON avec tous les todos de db.json.

Pour en savoir plus sur Json-Server, assurez-vous de consulter les API Mock REST en utilisant JSON-Server.

Stockage de l'URL de l'API

Maintenant que nous avons le dos en place, nous devons stocker son URL dans notre application angulaire.

Idéalement, nous devrions être capables de le faire:

  1. Stockez l'URL en un seul endroit afin que nous ne devons le changer qu'une seule fois que lorsque nous devons modifier sa valeur
  2. faire connecter notre application à une API de développement pendant le développement et se connecter à une API de production en production.

Heureusement, Angular CLI prend en charge les environnements. Par défaut, il existe deux environnements: le développement et la production, à la fois avec un fichier d'environnement correspondant: src / environnements / environnement.ts et ‘src / Environments / Environment.prod.ts.

Ajoutons notre URL de l'API aux deux fichiers:

<span>npm install -g @angular/cli@latest
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
npm uninstall -g @angular/cli angular-cli
npm cache clean
<span>npm install -g @angular/cli@latest
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cela nous permettra plus tard d'obtenir l'URL de l'API de notre environnement dans notre application angulaire en faisant:

<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git
</span><span>cd angular-todo-app
</span><span>git checkout part-2
</span><span>npm install
</span>ng serve
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Lorsque nous exécutons Ng Serv ou Ng Build, Angular CLI utilise la valeur spécifiée dans l'environnement de développement (Src / Environments / Environment.TS).

Mais lorsque nous exécutons Ng Serve - Environment prod ou ng build --environment prod, Angular CLI utilise la valeur spécifiée dans Src / Environments / Environment.Prod.ts.

C'est exactement ce que nous avons besoin pour utiliser une URL API différente pour le développement et la production, sans avoir à modifier notre code.

L'application dans cette série d'articles n'est pas hébergée dans la production, nous spécifions donc la même URL de l'API dans notre environnement de développement et de production. Cela nous permet d'exécuter NG Service - Environment Prod ou Ng Build - Environment se produit localement pour voir si tout fonctionne comme prévu.

Vous pouvez trouver le mappage entre Dev et Prod et leurs fichiers d'environnement correspondants dans .angular-cli.json:

<span>npm install json-server --save
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Vous pouvez également créer des environnements supplémentaires tels que la mise en scène en ajoutant une clé:

<span>{
</span>  <span>"todos": [
</span>    <span>{
</span>      <span>"id": 1,
</span>      <span>"title": "Read SitePoint article",
</span>      <span>"complete": false
</span>    <span>},
</span>    <span>{
</span>      <span>"id": 2,
</span>      <span>"title": "Clean inbox",
</span>      <span>"complete": false
</span>    <span>},
</span>    <span>{
</span>      <span>"id": 3,
</span>      <span>"title": "Make restaurant reservation",
</span>      <span>"complete": false
</span>    <span>}
</span>  <span>]
</span><span>}
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

et création du fichier d'environnement correspondant.

Pour en savoir plus sur les environnements CLI angulaires, assurez-vous de consulter le guide de référence CLI angulaire ultime.

Maintenant que notre URL API est stockée dans notre environnement, nous pouvons créer un service angulaire pour communiquer avec l'API REST Back End.

Création du service pour communiquer avec l'API REST Back End

Utilisons Angular CLI pour créer un apicers pour communiquer avec notre API REST Back End:

<span>"scripts": {
</span>  <span>...
</span>  <span>"json-server": "json-server --watch db.json"
</span><span>}
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cela donne la sortie suivante:

<span>npm install -g @angular/cli@latest
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

L'option - module app.module.ts indique à Angular CLI non seulement de créer le service, mais aussi de l'enregistrer en tant que fournisseur dans le module angulaire défini dans app.module.ts.

Ouvrir SRC / APP / API.SERVICE.TS:

npm uninstall -g @angular/cli angular-cli
npm cache clean
<span>npm install -g @angular/cli@latest
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ensuite, nous injectons notre environnement et le service HTTP intégré d'Angular:

<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git
</span><span>cd angular-todo-app
</span><span>git checkout part-2
</span><span>npm install
</span>ng serve
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Avant de mettre en œuvre les méthodes dont nous avons besoin, jetons un œil au service HTTP d'Angular.

Si vous n'êtes pas familier avec la syntaxe, pourquoi ne pas acheter notre cours premium, en introduisant TypeScript.

Le service HTTP angulaire

Le service HTTP angulaire est disponible en classe injectable de @ Angular / http.

Il est construit au-dessus de XHR / JSONP et nous fournit un client HTTP que nous pouvons utiliser pour faire des demandes HTTP à partir de notre application angulaire.

Les méthodes suivantes sont disponibles pour effectuer des demandes HTTP:

  • supprimer (URL, options): effectuez une demande de suppression
  • get (url, options): effectuez une demande de get
  • tête (URL, options): effectuez une demande de tête
  • Options (URL, Options): Effectuez une demande d'options
  • Patch (URL, corps, options): effectuez une demande de patch
  • Post (URL, corps, options): effectuez une demande de post
  • put (URL, corps, options): effectuez une demande de put.

Chacune de ces méthodes renvoie un RXJ observable.

Contrairement aux méthodes de service AngularJS 1.x HTTP, qui ont rendu les promesses, les méthodes de service HTTP angulaires renvoient les observables.

Ne vous inquiétez pas si vous n'êtes pas encore familier avec les observables RXJS. Nous n'avons besoin que des bases pour mettre notre application en cours d'exécution. Vous pouvez en savoir progressivement plus sur les opérateurs disponibles lorsque votre application les nécessite et le site Web Reactivex offre une documentation fantastique.

Si vous souhaitez en savoir plus sur les observables, cela peut également valoir la peine de consulter l'introduction de SitePoint à la programmation réactive fonctionnelle avec RXJS.

Implémentation des méthodes d'applications

si nous repensons aux points de terminaison que notre API REST expose:

  • get / todos: obtenez tous les todos existants

  • get / todos /: id: obtenez un todo existant

  • post / todos: créez un nouveau todo

  • put / todos /: id: mettez à jour un todo existant

  • delete / todos /: id: supprimer un todo existant

Nous pouvons déjà créer un aperçu approximatif des méthodes dont nous avons besoin et de leurs méthodes HTTP angulaires correspondantes:

<span>npm install json-server --save
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Examinons de plus près chacune des méthodes.

getAllTodos ()

La méthode getAllTodos () nous permet d'obtenir tous les todos de l'API:

<span>{
</span>  <span>"todos": [
</span>    <span>{
</span>      <span>"id": 1,
</span>      <span>"title": "Read SitePoint article",
</span>      <span>"complete": false
</span>    <span>},
</span>    <span>{
</span>      <span>"id": 2,
</span>      <span>"title": "Clean inbox",
</span>      <span>"complete": false
</span>    <span>},
</span>    <span>{
</span>      <span>"id": 3,
</span>      <span>"title": "Make restaurant reservation",
</span>      <span>"complete": false
</span>    <span>}
</span>  <span>]
</span><span>}
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Tout d'abord, nous faisons une demande de get pour obtenir tous les todos de notre API:

<span>"scripts": {
</span>  <span>...
</span>  <span>"json-server": "json-server --watch db.json"
</span><span>}
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cela renvoie un observable.

Nous appelons ensuite la méthode map () sur l'observable pour transformer la réponse de l'API en un tableau d'objets TODO:

<span>npm install -g @angular/cli@latest
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

La réponse HTTP entrante est une chaîne, nous appelons donc d'abord la réponse.json () pour analyser la chaîne JSON à sa valeur JavaScript correspondante.

nous boucle ensuite sur les todos de la réponse de l'API et renvoyons un tableau d'instances TODO. Notez que cette deuxième utilisation de map () utilise array.prototype.map (), pas l'opérateur RXJS.

Enfin, nous attachons un gestionnaire d'erreurs pour enregistrer les erreurs de potentiel à la console:

npm uninstall -g @angular/cli angular-cli
npm cache clean
<span>npm install -g @angular/cli@latest
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Nous définissons le gestionnaire d'erreurs dans une méthode distincte afin que nous puissions le réutiliser dans d'autres méthodes:

<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git
</span><span>cd angular-todo-app
</span><span>git checkout part-2
</span><span>npm install
</span>ng serve
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Avant de pouvoir exécuter ce code, nous devons importer les dépendances nécessaires de la bibliothèque RXJS:

<span>npm install json-server --save
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Notez que la bibliothèque RXJS est énorme. Au lieu d'importer l'intégralité de la bibliothèque RXJS à l'aide d'import * en tant que RX à partir de «RXJS / RX», il est recommandé d'importer uniquement les pièces dont vous avez besoin. Cela réduira considérablement la taille de votre bundle de code résultant au minimum.

Dans notre application, nous importons la classe observable:

<span>{
</span>  <span>"todos": [
</span>    <span>{
</span>      <span>"id": 1,
</span>      <span>"title": "Read SitePoint article",
</span>      <span>"complete": false
</span>    <span>},
</span>    <span>{
</span>      <span>"id": 2,
</span>      <span>"title": "Clean inbox",
</span>      <span>"complete": false
</span>    <span>},
</span>    <span>{
</span>      <span>"id": 3,
</span>      <span>"title": "Make restaurant reservation",
</span>      <span>"complete": false
</span>    <span>}
</span>  <span>]
</span><span>}
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Nous importons les trois opérateurs dont notre code nécessite:

<span>"scripts": {
</span>  <span>...
</span>  <span>"json-server": "json-server --watch db.json"
</span><span>}
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Les opérateurs d'importation garantissent que nos instances observables ont les méthodes correspondantes qui leur sont fixées.

Si nous n'avons pas d'importation 'RXJS / ADD / OPÉRATEUR / MAP' dans notre code, alors les suivants ne fonctionneraient pas:

<span>npm run json-server
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

C'est parce que l'observable renvoyé par ce.http.get n'aurait pas de méthode map ().

Nous n'avons à importer les opérateurs qu'une seule fois pour activer les méthodes observables correspondantes à l'échelle mondiale dans votre application. Cependant, les importer plus d'une fois n'est pas un problème et n'augmentera pas la taille du bundle résultant.

getTodoByid ()

La méthode getTodoByid () nous permet d'obtenir un seul todo:

  <span>\{^_^}/ hi!
</span>
  Loading db.json
  Done

  Resources
  http://localhost:3000/todos

  Home
  http://localhost:3000
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Nous n'avons pas besoin de cette méthode dans notre application, mais elle est incluse pour vous donner une idée de ce à quoi il ressemblerait.

CreateTodo ()

La méthode CreateTodo () nous permet de créer un nouveau todo:

<span>// src/environments/environment.ts
</span><span>// used when we run `ng serve` or `ng build`
</span><span>export const environment = {
</span>  production<span>: false,
</span>
  <span>// URL of development API
</span>  apiUrl<span>: 'http://localhost:3000'
</span><span>};
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion

Nous effectuons d'abord une demande postale à notre API et passons dans les données comme deuxième argument:

<span>// src/environments/environment.prod.ts
</span><span>// used when we run `ng serve --environment prod` or `ng build --environment prod`
</span><span>export const environment = {
</span>  production<span>: true,
</span>
  <span>// URL of production API
</span>  apiUrl<span>: 'http://localhost:3000'
</span><span>};
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion

Nous transformons ensuite la réponse en un objet TODO:

<span>import { environment } from 'environments/environment';
</span>
<span>// we can now access environment.apiUrl
</span><span>const API_URL = environment.apiUrl;
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion

updateTodo ()

La méthode UpdateTodo () nous permet de mettre à jour un seul TODO:

<span>"environments": {
</span>  <span>"dev": "environments/environment.ts",
</span>  <span>"prod": "environments/environment.prod.ts"
</span><span>}
</span>
Copier après la connexion
Copier après la connexion

Nous effectuons d'abord une demande de put à notre API et passons les données comme deuxième argument:

<span>"environments": {
</span>  <span>"dev": "environments/environment.ts",
</span>  <span>"staging": "environments/environment.staging.ts",
</span>  <span>"prod": "environments/environment.prod.ts"
</span><span>}
</span>
Copier après la connexion

Nous transformons ensuite la réponse en un objet TODO:

ng generate <span>service Api --module app.module.ts
</span>
Copier après la connexion

DeleTeToDoByid ()

La méthode DeleTeToDoById () nous permet de supprimer un seul Todo:

installing <span>service
</span>  create src/app/api.service.spec.ts
  create src/app/api.service.ts
  update src/app/app.module.ts
Copier après la connexion

Nous effectuons d'abord une demande de suppression à notre API:

<span>import { Injectable } from '@angular/core';
</span>
<span><span>@Injectable</span>()
</span><span>export class ApiService {
</span>
  <span>constructor() { }
</span>
<span>}
</span>
Copier après la connexion

Nous transformons ensuite la réponse en null:

<span>import { Injectable } from '@angular/core';
</span><span>import { environment } from 'environments/environment';
</span><span>import { Http } from '@angular/http';
</span>
<span>const API_URL = environment.apiUrl;
</span>
<span><span>@Injectable</span>()
</span><span>export class ApiService {
</span>
  <span>constructor(
</span>    <span>private http: Http
</span>  <span>) {
</span>  <span>}
</span>
<span>}
</span>
Copier après la connexion

Nous n'avons pas vraiment besoin de transformer la réponse ici et nous avons pu laisser de côté cette ligne. Il est simplement inclus pour vous donner une idée de la façon dont vous pouvez traiter la réponse si vous renvoyer des données lorsque vous effectuez une demande de suppression.

Voici le code complet de notre application:

<span>npm install -g @angular/cli@latest
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Maintenant que nous avons notre application en place, nous pouvons l'utiliser pour laisser notre tododataservice communiquer avec notre API REST Back End.

Mise à jour de TododataService

Actuellement, notre TododataService stocke toutes les données en mémoire:

npm uninstall -g @angular/cli angular-cli
npm cache clean
<span>npm install -g @angular/cli@latest
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Pour laisser notre tododataservice communiquer avec notre API REST, nous devons injecter notre nouvel apivice:

<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git
</span><span>cd angular-todo-app
</span><span>git checkout part-2
</span><span>npm install
</span>ng serve
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Nous mettons également à jour ses méthodes pour déléguer tous les travaux aux méthodes correspondantes dans l'APISERVICE:

<span>npm install json-server --save
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Nos nouvelles implémentations de méthode semblent beaucoup plus simples car la logique de données est désormais gérée par l'API REST Back End.

Cependant, il y a une différence importante. Les anciennes méthodes contenaient du code synchrone et renvoyaient immédiatement une valeur. Les méthodes mises à jour contiennent du code asynchrone et renvoient un observable.

Cela signifie que nous devons également mettre à jour le code qui appelle les méthodes TododataService pour gérer correctement les observables.

Mise à jour de AppComponent

Actuellement, l'AppComponent s'attend à ce que le TododataService renvoie directement les objets et les tableaux JavaScript:

<span>{
</span>  <span>"todos": [
</span>    <span>{
</span>      <span>"id": 1,
</span>      <span>"title": "Read SitePoint article",
</span>      <span>"complete": false
</span>    <span>},
</span>    <span>{
</span>      <span>"id": 2,
</span>      <span>"title": "Clean inbox",
</span>      <span>"complete": false
</span>    <span>},
</span>    <span>{
</span>      <span>"id": 3,
</span>      <span>"title": "Make restaurant reservation",
</span>      <span>"complete": false
</span>    <span>}
</span>  <span>]
</span><span>}
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

mais nos nouvelles méthodes d'apisenvice renvoient les observables.

similaire aux promesses, les observables sont de nature asynchrone, nous devons donc mettre à jour le code pour gérer les réponses observables en conséquence:

Si nous appelons actuellement la méthode toDodataService.getallTodos () dans get todos ():

<span>"scripts": {
</span>  <span>...
</span>  <span>"json-server": "json-server --watch db.json"
</span><span>}
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

La méthode tododataservice.getAllTodos () appelle la méthode APIService.getallTodos () correspondante:

<span>npm run json-server
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cela, à son tour, demande au service HTTP angulaire pour effectuer une demande de GET HTTP:

  <span>\{^_^}/ hi!
</span>
  Loading db.json
  Done

  Resources
  http://localhost:3000/todos

  Home
  http://localhost:3000
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cependant, il y a une chose importante dont nous devons nous souvenir!

Tant que nous ne souscrivons pas à l'observable renvoyé par:

<span>// src/environments/environment.ts
</span><span>// used when we run `ng serve` or `ng build`
</span><span>export const environment = {
</span>  production<span>: false,
</span>
  <span>// URL of development API
</span>  apiUrl<span>: 'http://localhost:3000'
</span><span>};
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion

Aucune demande HTTP réelle n'est faite.

Pour vous abonner à un observable, nous pouvons utiliser la méthode abonné (), qui prend trois arguments:

  • onNext: Une fonction qui s'appelle lorsque l'observable émet une nouvelle valeur
  • onerror: une fonction qui s'appelle lorsque l'observable lance une erreur
  • oncompleted: une fonction qui s'appelle lorsque l'observable s'est terminé gracieusement.

Réécrivons notre code actuel:

<span>// src/environments/environment.prod.ts
</span><span>// used when we run `ng serve --environment prod` or `ng build --environment prod`
</span><span>export const environment = {
</span>  production<span>: true,
</span>
  <span>// URL of production API
</span>  apiUrl<span>: 'http://localhost:3000'
</span><span>};
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cela chargera les todos de manière asynchrone lorsque l'apponent apposant est initialisé:

<span>import { environment } from 'environments/environment';
</span>
<span>// we can now access environment.apiUrl
</span><span>const API_URL = environment.apiUrl;
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion

Tout d'abord, nous définissons une propriété publique, Todos et définissons sa valeur initiale sur un tableau vide.

Nous utilisons ensuite la méthode NgonInit () pour vous abonner à ce.tododataservice.getAllTodos (), et lorsqu'une valeur arrive, nous l'avons attribué à ce.todos, écrasant sa valeur initiale d'un tableau vide.

Maintenant, mettons à jour la méthode onaddtodo (TODO) pour gérer également une réponse observable:

<span>"environments": {
</span>  <span>"dev": "environments/environment.ts",
</span>  <span>"prod": "environments/environment.prod.ts"
</span><span>}
</span>
Copier après la connexion
Copier après la connexion

Encore une fois, nous utilisons la méthode abonné () pour s'abonner à l'observable renvoyé par ce.todataService.addtodo (TODO), et lorsque la réponse arrive, nous ajoutons le TODO nouvellement créé à la liste actuelle de Todos.

Nous répétons le même exercice pour les autres méthodes jusqu'à ce que notre apposant apparente ceci:

<span>npm install -g @angular/cli@latest
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

c'est tout; Toutes les méthodes sont désormais capables de gérer les observables renvoyés par les méthodes de tododataservice.

Remarquez qu'il n'est pas nécessaire de vous désabonner manuellement lorsque vous vous abonnez à un observable qui est renvoyé par le service HTTP angulaire. Angular nettoiera tout pour vous empêcher les fuites de mémoire.

Voyons si tout fonctionne comme prévu.

l'essayer

Ouvrez une fenêtre de terminal.

À partir de la racine de notre répertoire d'application, démarrez l'API REST Back End:

npm uninstall -g @angular/cli angular-cli
npm cache clean
<span>npm install -g @angular/cli@latest
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ouvrez une deuxième fenêtre de terminal.

Encore une fois, à partir de la racine de notre répertoire d'application, servez l'application angulaire:

<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git
</span><span>cd angular-todo-app
</span><span>git checkout part-2
</span><span>npm install
</span>ng serve
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Maintenant, naviguez sur votre navigateur vers http: // localhost: 4200.

Si tout se passe bien, vous devriez voir ceci:

Angular et RXJS: ajout d'une API REST

Si vous voyez une erreur, vous pouvez comparer votre code à la version de travail sur github.

génial! Notre application communique maintenant avec l'API REST Back End!

Astuce latérale: Si vous souhaitez exécuter NPM, exécuter JSON-Server et NG servir dans le même terminal, vous pouvez utiliser simultanément pour exécuter les deux commandes simultanément sans ouvrir plusieurs fenêtres ou onglets de terminal.

Exécutons nos tests unitaires pour vérifier que tout fonctionne comme prévu.

exécuter nos tests

Ouvrez une troisième fenêtre de terminal.

Encore une fois, à partir de la racine de votre répertoire d'application, exécutez les tests unitaires:

<span>npm install json-server --save
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Il semble que 11 tests unitaires échouent:

Voyons pourquoi nos tests échouent et comment nous pouvons les réparer.

Fixation de nos tests unitaires

Tout d'abord, ouvrons Src / Todo-data.service.spec.ts:

<span>{
</span>  <span>"todos": [
</span>    <span>{
</span>      <span>"id": 1,
</span>      <span>"title": "Read SitePoint article",
</span>      <span>"complete": false
</span>    <span>},
</span>    <span>{
</span>      <span>"id": 2,
</span>      <span>"title": "Clean inbox",
</span>      <span>"complete": false
</span>    <span>},
</span>    <span>{
</span>      <span>"id": 3,
</span>      <span>"title": "Make restaurant reservation",
</span>      <span>"complete": false
</span>    <span>}
</span>  <span>]
</span><span>}
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

La plupart des tests unitaires défaillants visent à vérifier la gestion des données. Ces tests ne sont plus nécessaires car la gestion des données est désormais effectuée par notre API REST à l'arrière au lieu du tododataservice, alors supprimons les tests obsolètes:

<span>"scripts": {
</span>  <span>...
</span>  <span>"json-server": "json-server --watch db.json"
</span><span>}
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Si nous exécutons maintenant les tests unitaires, nous obtenons une erreur:

<span>npm run json-server
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

L'erreur est lancée car TestBed.ConfigureTestingModule () crée un module temporaire pour les tests et l'injecteur du module temporaire n'est conscient d'aucun apivice.

Pour informer l'injecteur de l'APISERVICE, nous devons l'enregistrer auprès du module temporaire en répertoriant l'apisenservice en tant que fournisseur dans l'objet de configuration qui est transmis à Testbed.ConfigureTestingModule ():

  <span>\{^_^}/ hi!
</span>
  Loading db.json
  Done

  Resources
  http://localhost:3000/todos

  Home
  http://localhost:3000
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cependant, si nous le faisons, notre test unitaire utilisera notre véritable apicers, qui se connecte à notre API REST.

Nous ne voulons pas que notre Runner de test se connecte à une véritable API lors de l'exécution de nos tests unitaires, alors créons un APIMOCKSERVICE pour se moquer de la véritable apice-service dans les tests unitaires.

Création d'un APIMOCKSERVICE

Utilisons Angular CLI pour générer un nouveau APIMOCKSERVICE:

<span>npm install -g @angular/cli@latest
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cela montre ce qui suit:

npm uninstall -g @angular/cli angular-cli
npm cache clean
<span>npm install -g @angular/cli@latest
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ensuite, nous mettons en œuvre les mêmes méthodes qu'apisservice, mais nous laissons les méthodes renvoyer des données simulées au lieu de faire des demandes HTTP:

<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git
</span><span>cd angular-todo-app
</span><span>git checkout part-2
</span><span>npm install
</span>ng serve
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Remarquez comment chaque méthode renvoie de nouvelles données fraîches. Cela peut sembler un peu répétitif, mais c'est une bonne pratique. Si un test unitaire modifie les données simulées, le changement ne peut jamais affecter les données d'un autre test unitaire.

Maintenant que nous avons un service APIMOCKSERVICE, nous pouvons remplacer l'apisservice dans nos tests unitaires avec APIMOCKSERVICE.

Ouvrir Src / Todo-data.service.spec.ts à nouveau.

Dans le tableau des fournisseurs, nous disons à l'injecteur de fournir le service APIMOCKS chaque fois que l'APISERVIC est demandé:

<span>npm install json-server --save
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Si nous réévaluons maintenant les tests unitaires, l'erreur a disparu. Super!

Nous avons encore deux autres tests d'échec, cependant:

<span>{
</span>  <span>"todos": [
</span>    <span>{
</span>      <span>"id": 1,
</span>      <span>"title": "Read SitePoint article",
</span>      <span>"complete": false
</span>    <span>},
</span>    <span>{
</span>      <span>"id": 2,
</span>      <span>"title": "Clean inbox",
</span>      <span>"complete": false
</span>    <span>},
</span>    <span>{
</span>      <span>"id": 3,
</span>      <span>"title": "Make restaurant reservation",
</span>      <span>"complete": false
</span>    <span>}
</span>  <span>]
</span><span>}
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Les erreurs sont similaires à celle que nous venons de corriger.

Pour corriger la première erreur, ouvrons SRC / API.Service.Spec.ts:

<span>"scripts": {
</span>  <span>...
</span>  <span>"json-server": "json-server --watch db.json"
</span><span>}
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Le test échoue avec un message aucun fournisseur pour http!, Indiquant que nous devons ajouter un fournisseur pour http.

Encore une fois, nous ne voulons pas que le service HTTP envoie de vraies demandes HTTP, nous instancons donc un simulation de service HTTP qui utilise Angular’s ​​MockBackend:

<span>npm run json-server
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ne vous inquiétez pas si la configuration du module de test semble un peu écrasant.

Vous pouvez en savoir plus sur la configuration du test unitaire dans la documentation officielle pour tester les applications angulaires.

pour corriger l'erreur finale:

  <span>\{^_^}/ hi!
</span>
  Loading db.json
  Done

  Resources
  http://localhost:3000/todos

  Home
  http://localhost:3000
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ouvrir Src / App ...Component.Spec.ts:

<span>// src/environments/environment.ts
</span><span>// used when we run `ng serve` or `ng build`
</span><span>export const environment = {
</span>  production<span>: false,
</span>
  <span>// URL of development API
</span>  apiUrl<span>: 'http://localhost:3000'
</span><span>};
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ensuite, fournissez à l'injecteur de notre simulation d'apisservice:

<span>// src/environments/environment.prod.ts
</span><span>// used when we run `ng serve --environment prod` or `ng build --environment prod`
</span><span>export const environment = {
</span>  production<span>: true,
</span>
  <span>// URL of production API
</span>  apiUrl<span>: 'http://localhost:3000'
</span><span>};
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion

Hourra! Tous nos tests passent:

Angular et RXJS: ajout d'une API REST

Nous avons connecté avec succès notre application angulaire à notre API REST Back End.

Pour déployer notre application dans un environnement de production, nous pouvons maintenant s'exécuter:

<span>import { environment } from 'environments/environment';
</span>
<span>// we can now access environment.apiUrl
</span><span>const API_URL = environment.apiUrl;
</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion

Nous téléchargeons également le répertoire DIST généré sur notre serveur d'hébergement. À quel point est-ce doux?

Recaptons ce que nous avons appris.

Résumé

Dans le premier article, nous avons appris à:

  • Initialiser notre application TODO en utilisant CLI angulaire
  • Créez une classe TODO pour représenter des todos individuels
  • Créer un service TododataService pour créer, mettre à jour et supprimer les todos
  • Utilisez le composant AppComponent pour afficher l'interface utilisateur
  • Déployez notre application sur les pages GitHub.

Dans le deuxième article, nous avons refactorisé AppComponent pour déléguer la plupart de ses travaux à:

  • A TodistComponent pour afficher une liste de Todos
  • a todolistitemComponent pour afficher un seul TODO
  • a todolistheaderComponent pour créer un nouveau todo
  • A TodolistFooterComponent pour montrer combien de todos reste.

Dans ce troisième article, nous:

  • a créé une simulation API REST Back End
  • stocké l'URL de l'API comme variable d'environnement
  • a créé un apice pour communiquer avec l'API REST Back End
  • a mis à jour le tododataService pour utiliser le nouvel apicerservice
  • a mis à jour l'AppComponent pour gérer les appels API asynchrones
  • a créé un APIMOCKSERVICE pour éviter de vrais appels HTTP lors de l'exécution des tests unitaires.

Dans le processus, nous avons appris:

  • Comment utiliser les variables d'environnement pour stocker les paramètres d'application
  • Comment utiliser le client HTTP angulaire pour effectuer des demandes HTTP
  • Comment gérer les observables qui sont renvoyés par le client HTTP angulaire
  • Comment se moquer des appels HTTP pour éviter de vraies demandes HTTP lors de l'exécution des tests unitaires.

Tout le code de cet article est disponible sur github.

Dans la quatrième partie, nous présenterons le routeur et le refacteur AppComponent pour utiliser le routeur pour récupérer les todos de l'arrière.

Dans la deuxième partie, nous implémenterons l'authentification pour éviter un accès non autorisé à notre application.

Cet article a été revu par des pairs par Vildan Softic. Merci à tous les pairs examinateurs de SitePoint pour avoir fait du contenu SitePoint le meilleur possible!

Questions fréquemment posées (FAQ) sur le service API Angular et RXJS avec REST Backend

quel est le rôle des RXJ dans le service API angulaire?

RXJS, abrégé pour des extensions réactives pour JavaScript, est une bibliothèque pour la programmation réactive qui utilise des observables, pour faciliter la composition asynchronique ou basée sur un rappel qui utilise des observables, pour faciliter la composition asynchronie ou basée sur un rappel qui utilise des observables, pour faciliter la composition asynchronie ou basée sur un rappel qui utilise des observables, pour comparer plus facile de composer asynchrones ou basés sur un rappel qui utilisent des observables, pour faciliter la composition d'asynchrones ou de rappel code. Dans le contexte du service API angulaire, RXJS joue un rôle crucial dans la gestion des opérations asynchrones. Il fournit un moyen de créer et de travailler avec des observables qui permet de gérer plusieurs opérations asynchrones, de gérer les erreurs et même d'annuler les opérations. Cela en fait un outil puissant pour travailler avec les demandes HTTP, qui sont intrinsèquement asynchrones.

Comment angulaire interagit-il avec le backend REST?

Angular interagit-il avec un backend REST via le module HTTPClient. Ce module fournit une API simplifiée pour la fonctionnalité HTTP. Il permet à Angular de faire des demandes HTTP au serveur, d'envoyer des données utilisateur ou de récupérer des données du serveur. Le module HTTPClient comprend également des méthodes de demandes telles que GET, POST, PUT, DELETE, qui correspondent aux méthodes HTTP utilisées dans les API RESTful.

Comment puis-je gérer les erreurs dans le service API angular? > La gestion des erreurs est une partie essentielle de toute application. Dans le service API angulaire, vous pouvez gérer les erreurs à l'aide de l'opérateur Catcherror de RXJS. Cet opérateur attrape l'erreur sur l'observable et vous permet de le gérer ou de renvoyer un nouveau observable. Vous pouvez l'utiliser dans la méthode du tuyau de l'observable, après la méthode qui pourrait lancer une erreur.

Comment puis-je annuler une demande dans le service API angulaire?

Dans le service API angulaire, vous pouvez annuler une demande en utilisant la méthode de désabonnement de l'objet d'abonnement. Lorsque vous vous abonnez à un observable, il renvoie un objet d'abonnement. Cet objet a une méthode de désabonnement que vous pouvez appeler pour annuler l'abonnement, et par conséquent, la demande HTTP.

Comment puis-je réessayer une demande échouée dans le service API angulaire?

dans le service API angulaire , vous pouvez réessayer une demande échouée en utilisant les opérateurs de réessayer ou de réessayer de RXJS. L'opérateur de réessayer remonte à l'observable, répétant efficacement la demande HTTP. L'opérateur de réessayer vous permet de définir une condition pour réessayer la demande.

Comment puis-je faire plusieurs demandes dans le service API Angular?

Dans le service API angulaire, vous pouvez faire plusieurs demandes en utilisant le fourkjoin Fonction de RXJS. Cette fonction prend un tableau d'observables et renvoie un nouveau observable qui émet un tableau des résultats des observables d'entrée, une fois qu'ils ont tous terminé.

Comment puis-je transformer les données de réponse dans le service API angulaire?

Dans le service API angulaire, vous pouvez transformer les données de réponse à l'aide de l'opérateur MAP à partir de RXJS. Cet opérateur applique une fonction donnée à chaque élément émis par l'observable et renvoie un nouveau observable qui émet les résultats.

Comment puis-je envoyer des données au serveur dans Angular API Service?

En Service API Angular, vous pouvez envoyer des données au serveur à l'aide de la méthode post du module HTTPClient. Cette méthode prend l'URL du serveur et les données à envoyer sous forme de paramètres, et renvoie un observable auquel vous pouvez vous abonner.

Comment puis-je mettre à jour les données sur le serveur dans Angular API Service?

Dans le service API angulaire, vous pouvez mettre à jour des données sur le serveur à l'aide de la méthode de put du module HTTPClient. Cette méthode prend l'URL du serveur, les données à mettre à jour et, éventuellement, les options de demande en tant que paramètres, et renvoie un observable à laquelle vous pouvez vous abonner.

comment puis-je supprimer les données du serveur dans Service API angulaire?

Dans le service API angulaire, vous pouvez supprimer les données du serveur à l'aide de la méthode de suppression du module HTTPClient. Cette méthode prend l'URL du serveur et éventuellement, les options de demande en tant que paramètres, et renvoie un observable à laquelle vous pouvez vous abonner.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal