Angular est l'un des choix les plus populaires lors de la création de nouvelles applications Web. De plus, les spécifications «Material Design» sont devenues un choix incontournable pour créer une expérience minimale et engageante aujourd'hui. Ainsi, tout nouveau projet «angulaire» utilise principalement la «bibliothèque de conception de matériaux angulaires» pour utiliser les composants qui suivent les spécifications de conception des matériaux. Des animations fluides aux commentaires d'interaction appropriés, tout cela est déjà disponible dans le cadre de la bibliothèque officielle de conception de matériaux pour angular.
Une fois l'application Web développée, l'étape suivante consiste à la déployer. C'est là que «Netlify» entre en scène. Avec son interface très facile à utiliser, son déploiement automatique, la répartition du trafic pour les tests A / B et diverses autres fonctionnalités, Netlify est sûrement un excellent outil.
L'article sera une procédure pas à pas pour créer une application Web Angular 8 en utilisant Angular officiel Bibliothèque Material Design. Nous allons créer une application Web de générateur de code QR entièrement basée sur Angular lorsqu'elle est hébergée sur Netlify.
Les fichiers de ce tutoriel peuvent être trouvés sur GitHub et une version de démonstration est déployée ici .
Mise en route
- Installez Angular 8
- Créez un compte Github
- Installez Git sur votre ordinateur, [19659010] Créez un compte Netlify .
Remarque : J'utiliserai VSCode et Microsoft Windows comme IDE et OS préférés, bien que les étapes soient similaires pour tout autre IDE sur n'importe quel autre système d'exploitation.
Une fois les conditions préalables remplies, commençons!
Mocks & Planning
Avant de commencer à créer le projet, il serait utile de planifier à l'avance: quel type d'interface utilisateur voulons-nous dans notre application? Y aura-t-il des pièces réutilisables? Comment l'application interagira-t-elle avec les services externes?
Vérifiez d'abord les simulations de l'interface utilisateur.
Ce sont les trois pages différentes qui seront contenues dans la demande. La page d'accueil sera le point de départ de notre candidature. La création d'une page QR doit traiter de la création d'un nouveau code QR. La page Historique affichera tous les codes QR enregistrés.
Les maquettes fournissent non seulement une idée de l'aspect et de la convivialité de l'application, mais elles séparent également la responsabilité de chaque page.
Une observation (à partir des maquettes) c'est qu'il semble que la barre de navigation supérieure soit commune à toutes les pages. Ainsi, la barre de navigation peut être créée en tant que composant réutilisable et réutilisée.
Maintenant que nous avons une bonne idée de l'apparence de l'application et de ce qui peut être réutilisé, commençons.
Création d'un nouveau Projet angulaire
Lancez VSCode, puis ouvrez une fenêtre de terminal dans VSCode pour générer un nouveau projet angulaire.
Le terminal s'ouvrira avec un chemin par défaut comme affiché dans l'invite. Vous pouvez passer à un répertoire préféré avant de continuer; dans le cas de Windows, j'utiliserai la commande cd
.
Pour aller de l'avant, angular-cli a une commande pour générer de nouveaux projets ng new
. Utilisez simplement le nom de projet que vous aimez et appuyez sur Entrée, par exemple ng new qr
.
Cela déclenchera la magie angulaire-cli; il fournira quelques options pour configurer certains aspects du projet, par exemple, en ajoutant un routage angulaire. Ensuite, en fonction des options sélectionnées, il générera tout le squelette du projet qui peut être exécuté sans aucune modification.
Pour ce didacticiel, entrez Oui pour le routage et sélectionnez CSS pour coiffant. Cela va générer un nouveau projet Angular:
Nous avons maintenant un projet Angular entièrement fonctionnel. Afin de nous assurer que tout fonctionne correctement, nous pouvons exécuter le projet en entrant cette commande dans le terminal: ng serve
. Euh oh, mais attendez, cela se traduit par une erreur.
Ne vous inquiétez pas. Chaque fois que vous créez un nouveau projet en utilisant angular-cli, il génère tout le squelette dans un dossier nommé d'après le nom du projet spécifié dans la commande ng new qr
. Ici, nous devrons remplacer le répertoire de travail actuel par celui qui vient d'être créé. Sous Windows, utilisez la commande cd qr
pour changer de répertoire.
Maintenant, essayez de relancer le projet à l'aide de ng serve
:
Ouvrez un navigateur Web, accédez à l'URL http: // localhost: 4200 pour voir le projet en cours d'exécution. La commande ng serve
exécute l'application sur le port 4200 par défaut.
CONSEIL: Pour l'exécuter sur un autre port, nous utilisons la commande ng serve --port
par exemple, ng serve --port 3000
.
Cela garantit que notre projet angulaire de base est opérationnel. Continuons.
Nous devons ajouter le dossier du projet à VSCode. Allez dans le menu "Fichier" et sélectionnez "Ouvrir le dossier" et sélectionnez le dossier du projet.
Ajouter la bibliothèque de matériaux angulaires
Pour installer la bibliothèque de matériaux angulaires, utilisez la commande suivante dans la fenêtre du terminal: ng add @ angular / material
. Cela posera (encore) quelques questions telles que le thème que vous voulez, si vous voulez des animations par défaut, si le support tactile est requis, entre autres. Nous allons simplement sélectionner le thème par défaut Indigo / Rose
Oui
pour ajouter HammerJS
bibliothèque et animations de navigateur.
La commande ci-dessus configure également l'ensemble du projet pour permettre la prise en charge des composants matériels.
- Il ajoute des dépendances de projet à package.json
- Il ajoute la police Roboto à le fichier index.html
- Il ajoute la police d'icône Material Design à votre index.html
- Il ajoute également quelques styles CSS globaux à:
- Supprimez les marges du corps,
- Définissez
hauteur: 100%
dans le code HTML et le corps, - Définissez Roboto comme police d'application par défaut.
Juste pour être sûr que tout va bien, vous pouvez réexécutez le projet à ce stade, mais vous ne remarquerez rien de nouveau.
Ajout de la page d'accueil
Le squelette de votre projet est maintenant prêt. Commençons par ajouter la page d'accueil.
Nous voulons garder notre page d'accueil simple, tout comme l'image ci-dessus. Cette page d'accueil utilise quelques composants matériels angulaires. Disséquons.
- La barre supérieure est un simple élément HTML
nav
qui contient le bouton de style de matériau,mat-button
avec une image et un texte comme enfant. La couleur de la barre est la même que la couleur primaire qui a été sélectionnée lors de l'ajout de la bibliothèque de matériaux angulaires; - Une image centrée;
- Une autre,
bouton mat
avec juste un texte comme enfant. Ce bouton permet aux utilisateurs d'accéder à la page d'historique; - Un badge de comptage,
matBadge
attaché au bouton ci-dessus, indiquant le nombre de codes QR enregistrés par l'utilisateur; - Une action flottante bouton,
mat-fab
dans le coin inférieur droit ayant la couleur d'accentuation du thème sélectionné.
En m'éloignant un peu, ajoutons d'abord les autres composants et services requis.
Ajout d'un en-tête
Comme prévu précédemment, la barre de navigation doit être réutilisée, créons-la en tant que composant angulaire séparé. Ouvrez le terminal dans VSCode et tapez ng g c header
(abréviation de ng generate header header) et appuyez sur Entrée. Cela va créer un nouveau dossier nommé "en-tête" qui contiendra quatre fichiers:
- header.component.css : utilisé pour fournir le style de ce composant;
- en-tête. component.html : pour ajouter des éléments HTML;
- header.component.spec.ts : pour écrire des cas de test;
- header.component.ts : pour écrire ajoutez la logique basée sur Typescript.
Pour que l'en-tête ressemble à ce qu'il était dans les maquettes, ajoutez le code HTML ci-dessous dans header.component. html :
CONSEIL: Pour ajouter une élévation pour n'importe quel composant de matériau, utilisez [class.mat-elevation-z8] = true
la valeur d'élévation peut être modifiée en changeant la valeur de z dans ce cas, il s'agit de z8
. Par exemple, pour modifier l'élévation à 16, utilisez [class.mat-elevation-z16] = true
.
Dans l'extrait de code HTML ci-dessus, deux éléments matériels angulaires sont utilisés: mat-icon
et bouton-mat / bouton-icône-mat
. Leur utilisation est très simple; tout d'abord, nous devons ajouter ces deux modules en tant que app.module.ts comme indiqué ci-dessous:
mat-icon
et mat-button
( Grand aperçu ) Cela nous permettra d'utiliser ces deux éléments de matériau angulaire n'importe où dans n'importe quel composant.
Pour ajouter des boutons de matériau, l'extrait de code HTML suivant est utilisé:
Il existe différents types d'éléments de bouton de matériau disponibles dans la bibliothèque de matériaux angulaires tels que bouton surélevé mat
bouton plat mat
mat-fab
et autres; remplacez simplement le mat-button
dans l'extrait de code ci-dessus par tout autre type.
L'autre élément est mat-icon
qui est utilisé pour afficher les icônes disponibles dans la bibliothèque d'icônes de matériaux. Lorsque la bibliothèque de matériaux angulaires a été ajoutée au début, une référence à la bibliothèque d'icônes de matériaux a également été ajoutée, ce qui nous a permis d'utiliser des icônes de la vaste gamme d'icônes.
L'utilisation est aussi simple que:
arrow_back
La balise imbriquée peut être utilisée pour changer la taille de l'icône (ici c'est
md-32
), ce qui rendra la taille de l'icône 32px en hauteur et en largeur. Cette valeur peut être md-24
md-48
etc. La valeur de la balise imbriquée est le nom de l'icône. (Le nom peut être trouvé ici pour toute autre icône.)
Accessibilité
Chaque fois que des icônes ou des images sont utilisées, il est impératif qu'elles fournissent suffisamment d'informations à des fins d'accessibilité ou pour un lecteur d'écran. utilisateur. ARIA (Accessible Rich Internet Applications) définit un moyen de rendre le contenu Web et les applications Web plus accessibles aux personnes handicapées.
Un point à noter est que les éléments HTML qui ont leur sémantique native (par exemple nav
) n'ont pas besoin d'attributs ARIA; le lecteur d'écran sait déjà que nav
est un élément de navigation et le lit comme tel.
Les spécifications ARIA sont divisées en trois catégories: rôles, états et propriétés. Supposons qu'un div
soit utilisé pour créer une barre de progression dans le code HTML. Il n'a pas de sémantique native; Le rôle ARIA peut décrire ce widget comme une barre de progression, la propriété ARIA peut indiquer sa caractéristique telle qu'elle peut être glissée. L'état ARIA décrira son état actuel tel que la valeur actuelle de la barre de progression. Voir l'extrait ci-dessous:
De même, un attribut aria très couramment utilisé: aria-hidden = true / false
est utilisé. La valeur true rend cet élément invisible pour les lecteurs d'écran.
Comme la plupart des éléments d'interface utilisateur utilisés dans cette application ont une signification sémantique native, les seuls attributs ARIA utilisés sont de spécifier les états de visibilité ARIA. Pour des informations détaillées, voir ceci .
Le header.component.html contient une certaine logique pour masquer et afficher le bouton de retour en fonction de la page en cours. De plus, le bouton Accueil contient également une image / logo qui doit être ajouté au dossier / assets . Téléchargez l'image de ici et enregistrez-la dans le dossier / assets
.
Pour le style de la barre de navigation, ajoutez le css ci-dessous dans header.component.css :
.navbar {
position: fixe;
en haut: 0;
gauche: 0;
à droite: 0;
indice z: 2;
fond: # 3f51b5;
affichage: flex;
flex-wrap: wrap;
align-items: centre;
rembourrage: 12px 16px;
}
.bouton {
Couleur blanche;
marge: 0px 10px;
}
Comme nous voulons conserver le composant d'en-tête réutilisable sur d'autres composants, afin de décider ce qui doit être affiché, nous les exigerons en tant que paramètres d'autres composants. Cela nécessite l'utilisation de @Input () décorateur qui se liera aux variables que nous avons utilisées dans header.component.html .
Ajoutez ces lignes dans le header.component Fichier .ts :
// Ajoutez ces trois lignes au-dessus de l'entrée du constructeur.
@Input () showBackButton: boolean;
@Input () currentTitle: string;
@Input () showHistoryNav: boolean;
constructor () {}
Les trois liaisons ci-dessus seront transmises en tant que paramètre à partir d'autres composants que le composant d'en-tête utilisera. Son utilisation sera plus claire une fois que nous irons de l'avant.
En poursuivant, nous devons créer une page d'accueil qui peut être représentée par un composant angulaire. Commençons donc par créer un autre composant; tapez ng g c home
dans le terminal pour générer automatiquement le composant home. Comme précédemment, un nouveau dossier nommé «home» sera créé contenant quatre fichiers différents. Avant de procéder à la modification de ces fichiers, ajoutons des informations de routage au module de routage angulaire.
Ajout de routage
Angulaire permet de mapper l'URL à un composant spécifique. Chaque fois qu'une navigation se produit, le framework Angular surveille l'URL et basé sur les informations présentes dans le fichier app-routing.module.ts ; il initialise le composant mappé. De cette façon, les différents composants ne doivent pas assumer la responsabilité d'initialiser d'autres composants. Dans notre cas, l'application dispose de trois pages navigables en cliquant sur différents boutons. Nous y parvenons en tirant parti du support de routage fourni par le framework Angular.
Le composant home doit être le point de départ de l'application. Ajoutons ces informations au fichier app-routing.module.ts .
La propriété path
est définie comme une chaîne vide; cela nous permet de mapper l'URL de l'application au composant de la page d'accueil, quelque chose comme google.com
qui montre la page d'accueil de Google.
CONSEIL: La valeur du chemin ne commence jamais par un " /
", mais utilise à la place une chaîne vide même si le chemin peut être comme recherche / café
.
Revenant au composant de la page d'accueil, remplacez le contenu de home.component.html avec ceci:
Le composant home comprend trois parties:
- Le composant d'en-tête réutilisable ici.
- Composant de profil ici .
- Le bouton d'action flottant en bas à droite.
L'extrait HTML ci-dessus montre comment le composant d'en-tête réutilisable est utilisé dans d'autres composants, nous utilisons simplement le sélecteur de composant et passons les paramètres requis.
Composant de profil est créé pour être utilisé comme corps de la page d'accueil, nous le créerons bientôt.
Le flottant bouton d'action avec l'icône +
est une sorte de bouton de matériau angulaire de type mat-fab
en bas à droite de l'écran. Il a la directive d'attribut routerLink
qui utilise les informations d'itinéraire fournies dans app-routing.module.ts
pour la navigation. Dans ce cas, le bouton a la valeur de l'itinéraire / create qui sera mappée pour créer un composant.
Pour faire flotter le bouton de création en bas à droite, ajoutez le code CSS ci-dessous dans home .component.css :
.fab-bottom-right {
position: fixe;
gauche: auto;
en bas: 5%;
à droite: 10%;
}
Étant donné que le composant de profil est censé gérer le corps de la page d'accueil, nous laisserons home.component.ts
intact.
Ajout du composant de profil
Terminal ouvert, tapez ng gc profile
et appuyez sur Entrée pour générer le composant de profil. Comme prévu précédemment, ce composant gérera le corps principal de la page d'accueil. Ouvrez profile.component.html
et remplacez son contenu par ceci:
L'extrait html ci-dessus montre comment utiliser l'élément matBadge
de la bibliothèque de matériaux. Pour pouvoir l'utiliser ici, nous devons suivre l'exercice habituel consistant à ajouter MatBadgeModule
au fichier app.module.ts
. Les badges sont de petits descripteurs de statut picturaux pour les éléments de l'interface utilisateur tels que les boutons, les icônes ou les textes. Dans ce cas, il est utilisé avec un bouton pour afficher le nombre de QR enregistrés par l'utilisateur. Le badge de bibliothèque de matériaux angulaires possède diverses autres propriétés, telles que la définition de la position du badge avec matBadgePosition
matBadgeSize
pour spécifier la taille, matBadgeColor
pour définir la couleur du badge. [19659005] Un autre élément d'image doit être ajouté au dossier d'éléments. Téléchargez et enregistrez-le dans le dossier des ressources du projet.
Ouvrez profile.component.css
et ajoutez ceci:
.center {
haut: 50%;
gauche: 50%;
position: absolue;
transformer: traduire (-50%, -50%);
}
.profile-child {
affichage: flex;
flex-direction: colonne;
align-items: centre;
}
.profile-actions {
rembourrage-dessus: 20px;
}
.avatar {
rayon frontière: 50%;
largeur: 180 px;
hauteur: 180px;
}
Le CSS ci-dessus atteindra l'interface utilisateur comme prévu.
Pour continuer, nous avons besoin d'une sorte de logique pour mettre à jour la valeur du nombre d'historique comme cela se reflétera dans le matBadge
utilisé précédemment. Ouvrez profile.component.ts
et ajoutez correctement l'extrait en surbrillance:
la classe d'exportation ProfileComponent implémente OnInit {
historyCount = 0;
constructeur (private storageUtilService: StorageutilService) {}
ngOnInit () {
this.updateHistoryCount ();
}
updateHistoryCount () {
this.historyCount = this.storageUtilService.getHistoryCount ();
}
}
Nous avons ajouté StorageutilService mais nous n'avons pas créé un tel service jusqu'à présent. Ignorant l'erreur, nous avons terminé notre composant de profil qui termine également notre composant de page d'accueil. Nous reverrons ce composant de profil après avoir créé notre service utilitaire de stockage. OK, alors faisons-le.
Stockage local
HTML5 propose une fonction de stockage Web qui peut être utilisée pour stocker des données localement. Cela offre beaucoup plus de stockage que les cookies, au moins 5 Mo contre 4 Ko. Il existe deux types de stockage Web avec une portée et une durée de vie différentes: Local et Session . Les premiers peuvent stocker des données de façon permanente tandis que les seconds sont temporaires et pour une seule session. La décision de sélectionner le type peut être basée sur le cas d'utilisation, dans notre scénario, nous voulons enregistrer sur plusieurs sessions, nous allons donc utiliser le stockage local .
Chaque élément de données est stocké dans une clé / paire de valeurs. Nous utiliserons le texte pour lequel le QR est généré comme clé et l'image QR encodée comme une chaîne base64 comme valeur. Créez un dossier d'entité, à l'intérieur du dossier, créez un nouveau fichier qr-object.ts
et ajoutez l'extrait de code comme indiqué:
Le contenu de la classe:
classe d'exportation QR {
texte: chaîne;
imageBase64: chaîne;
constructeur (text: string, imageBase64: string) {
this.imageBase64 = imageBase64;
this.text = text;
}
}
Chaque fois que l'utilisateur enregistre le QR généré, nous créons un objet de la classe ci-dessus et enregistrons cet objet à l'aide du service utilitaire de stockage.
Créez un nouveau dossier de service, nous allons créer de nombreux services, il est préférable de les regrouper.
Modifiez le répertoire de travail actuel en services, services cd
pour créer une nouvelle utilisation de service ng gs
il s'agit d'un raccourci pour ng generate service
tapez ng gs storageutil
et appuyez sur Entrée. Cela va créer deux fichiers: storageutil.service.ts
et storageutil.service.spec.ts
. Ce dernier sert à l'écriture de tests unitaires. Ouvrez storageutil.service.ts
et ajoutez ceci:
private historyCount: number;
constructeur () {}
saveHistory (clé: chaîne, élément: chaîne) {
localStorage.setItem (clé, élément)
this.historyCount = this.historyCount + 1;
}
readHistory (clé: chaîne): chaîne {
retour localStorage.getItem (clé)
}
readAllHistory (): Array {
const qrList = new Array ();
for (let i = 0; i
Importez la classe qr-object pour corriger les erreurs. Pour utiliser la fonction de stockage local, il n'est pas nécessaire d'importer quoi que ce soit de nouveau, utilisez simplement le mot-clé localStorage
pour enregistrer ou obtenir de la valeur en fonction d'une clé.
Maintenant, ouvrez à nouveau le fichier profile.component.ts
et importez la classe StorageutilService pour terminer correctement le composant de profil.
, nous pouvons voir que la page d'accueil est en place comme prévu.
Ajout d'une page de création de QR
Notre page d'accueil est prête, bien que le bouton créer / ajouter ne fasse rien. Ne vous inquiétez pas, la logique réelle a déjà été écrite. Nous avons utilisé une directive routerLink pour changer le chemin de base de l'URL en / create mais aucun mappage n'a été ajouté au fichier app-routing.module.ts
Créons un composant qui traitera de la création de nouveaux codes QR, tapez ng gc create-qr
et appuyez sur Entrée t o générer un nouveau composant.
Ouvrez le fichier app-routing.module.ts
et ajoutez l'entrée ci-dessous au tableau de routes :
{path: 'create' , composant: CreateQrComponent},
Ceci mappera le CreateQRComponent avec l'URL / create .
Ouvrez create-qr.components.html et remplacez le contenu par ceci:
L'extrait ci-dessus utilise de nombreux éléments de bibliothèque de matériaux angulaires. Comme prévu, il possède une référence de composant d'en-tête dans laquelle les paramètres requis sont transmis. Ensuite, le corps principal de la page de création est constitué d'une carte de matériau angulaire ou mat-card
centrée et élevée jusqu'à 12 pixels lorsque [class.mat-elevation-z12] = true
est utilisé. La carte de matériau est juste un autre type de conteneur qui peut être utilisé comme n'importe quelle autre étiquette div
. Bien que la bibliothèque de matériaux offre certaines propriétés pour disposer des informations bien définies dans une carte de mat
telles que le placement de l'image, le titre, le sous-titre, la description et l'action, comme on peut le voir ci-dessous.
Dans l'extrait de code HTML ci-dessus, nous avons utilisé mat-card
comme tout autre conteneur.
Un autre élément de bibliothèque de matériaux utilisé est matTooltip
c'est juste une autre info-bulle avec une facilité d'utilisation, affichée lorsque l'utilisateur survole ou appuie longuement sur un élément. Utilisez simplement l'extrait ci-dessous pour afficher l'info-bulle:
matTooltip = "Tout texte que vous souhaitez afficher"
Il peut être utilisé avec des boutons d'icônes ou tout autre élément d'interface utilisateur pour transmettre des informations supplémentaires. Dans le contexte de l'application, il affiche des informations sur le bouton de l'icône de fermeture. Pour modifier l'emplacement de l'info-bulle matTooltipPosition
est utilisé, par exemple
matTooltip = "Tout texte que vous souhaitez afficher" matTooltipPosition = "ci-dessus"
Outre matTooltip, mat-spinner
est utilisé pour afficher la progression du chargement. Lorsque l'utilisateur clique sur le bouton créer, un appel réseau est effectué, c'est alors que le spinner de progression est affiché. Lorsque l'appel réseau revient avec le résultat, nous masquons simplement le spinner. Il peut être utilisé simplement comme ceci:
showProgressSpinner est une variable booléenne qui est utilisée pour afficher / masquer le spinner de progression. La bibliothèque fournit également d'autres paramètres tels que [color] = ’accent’
pour changer la couleur, [mode] = ’indéterminé’
pour changer le type de spinner de progression. Un spinner de progression indéterminée n'affichera pas la progression de la tâche tandis qu'une variable déterminée peut avoir différentes valeurs pour refléter la progression de la tâche. Ici, un spinner indéterminé est utilisé car nous ne savons pas combien de temps l'appel réseau prendra.
La bibliothèque de matériaux fournit une variante de zone de texte conforme à la ligne directrice des matériaux, mais elle ne peut être utilisée que comme un descendant de mat- champ de formulaire
. L'utilisation de la zone de texte des matériaux est aussi simple que celle du HTML par défaut, comme ci-dessous:
matInput
est une directive qui permet à la balise native d'entrée
de fonctionner avec mat-form-field
. La propriété d'espace réservé
permet d'ajouter n'importe quel texte de conseil pour l'utilisateur.
CONSEIL: Utilisez cdkTextareaAutosize
propriété textarea pour le rendre auto-redimensionnable. cdkAutosizeMinRows
cdkAutosizeMaxRows
pour définir des lignes et des colonnes et les trois ensemble pour effectuer un redimensionnement automatique de la zone de texte jusqu'à ce qu'elle atteigne la limite maximale de lignes et de colonnes définie.
Pour utiliser toutes ces bibliothèques de matériaux , nous devons les ajouter dans le fichier app.module.ts
.
Une image d'espace réservé est utilisée dans le html, téléchargez et enregistrez-la dans le dossier d'actifs.
Le html ci-dessus nécessite également un style css, ouvrez le fichier create-qr.component.ts et ajoutez:
.qrCard {
affichage: flex;
flex-direction: colonne;
align-items: centre;
position: absolue;
haut: 50%;
gauche: 50%;
transformer: traduire (-50%, -50%);
largeur: 20%;
hauteur: 65%;
rembourrage: 50px 20px;
}
.qrContent {
affichage: flex;
flex-direction: colonne;
align-items: centre;
largeur: 100%;
}
.qrTextAreaDiv {
largeur: 100%;
affichage: flex;
flex-direction: rangée;
justifier-contenu: centre;
rembourrage: 0px 0px;
position: absolue;
en bas: 10%;
}
.createBtn {
gauche: 50%;
transformer: traduire (-50%, 0px);
largeur: 80%;
}
.createBtnDiv {
position: absolue;
en bas: 5%;
largeur: 100%;
}
.closeBtn {
affichage: flex;
flex-direction: row-reverse;
align-items: flex-end;
largeur: 100%;
marge en bas: 20 px;
}
.closeBtnFont {
taille de police: 32px;
couleur: rgba (0,0,0,0,75);
}
.qrImgDiv {
haut: 20%;
position: absolue;
affichage: flex;
flex-direction: colonne;
align-items: centre;
justifier-contenu: centre;
largeur: 100%;
}
.actionButtons {
affichage: flex;
flex-direction: rangée;
rembourrage-dessus: 20px;
}
Connectons l'interface utilisateur avec logique, ouvrons le fichier create-qr.component.ts
et ajoutons le code ci-dessous, en laissant les lignes déjà présentes:
la classe d'exportation CreateQrComponent implémente OnInit {
qrCodeImage = '../../../assets/download.png';
showProgressSpinner = false;
qrText: chaîne;
currentQR;
showBackButton = true;
title = 'Générer un nouveau code QR';
showHistoryNav = true;
constructeur (snackBar privé: MatSnackBar,
restutil privé: RestutilService,
private storageService: StorageutilService) {}
ngOnInit () {
}
createQrCode () {
// Vérifier si une valeur est donnée pour le texte du code qr
if (!! this.qrText) {
// Faire l'appel http pour charger le code qr
this.loadQRCodeImage (this.qrText);
} autre {
// Afficher le snack-bar
this.showSnackbar ('Entrez d'abord du texte')
}
}
public loadQRCodeImage (texte: chaîne) {
// Afficher le spinner de progression lors de la demande
this.showProgressSpinner = true;
// Déclencher l'appel API
this.restutil.getQRCode (text) .subscribe (image => {
// Reçu le résultat - comme un blob d'image - nécessite une analyse
this.createImageBlob (image);
}, erreur => {
console.log ('Impossible de récupérer le code QR à partir de l'url', erreur)
// Masque le spinner - affiche un message d'erreur correct
this.showProgressSpinner = false;
});
}
createImageBlob privé (image: Blob) {
// Créer un lecteur de fichiers pour lire le blob d'image
const reader = new FileReader ();
// Ajouter un écouteur d'événements pour "charger" - invoqué une fois la lecture du blob terminée
reader.addEventListener ('load', () => {
this.qrCodeImage = reader.result.toString ();
// Masque le spinner de progression
this.showProgressSpinner = false;
this.currentQR = reader.result.toString ();
}, faux);
// Lire le blob d'image s'il n'est pas nul ou non défini
if (image) {
reader.readAsDataURL (image);
}
}
saveQR () {
if (!! this.qrText) {
this.storageService.saveHistory (this.qrText, this.currentQR);
this.showSnackbar ('QR enregistré')
} autre {
// Afficher le snack-bar
this.showSnackbar ('Entrez d'abord du texte')
}
}
showSnackbar (msg: chaîne) {
// Afficher le snack-bar
this.snackBar.open (msg, '', {
durée: 2000,
});
}
}
Pour fournir aux utilisateurs des informations contextuelles, nous utilisons également MatSnackBar
de la bibliothèque de conception de matériaux. Cela apparaît comme une fenêtre contextuelle sous l'écran et reste pendant quelques secondes avant de disparaître. Ce n'est pas un élément mais plutôt un service qui peut être appelé à partir du code dactylographié. L'extrait ci-dessus avec le nom de méthode showSnackbar
montre comment ouvrir un snack-bar, mais avant qu'il puisse être utilisé, nous devons ajouter l'entrée MatSnackBar
dans le fichier app.module.ts comme we did for other material library elements.
TIP: In recent angular material library versions, there is no straightforward way to change the snackbar styling, instead one has to make two additions to the code, first is to use the below CSS to alter background and foreground colors:
::ng-deep snack-bar-container.snackbarColor {
background-color: rgba(63, 81, 181, 1);
}
::ng-deep .snackbarColor .mat-simple-snackbar {
color: white;
}
Second is to use a property called panelClass to set the style to the above CSS class:
this.snackBar.open(msg, '', {
duration: 2000,
panelClass: ['snackbarColor']
});
The above two combinations will allow custom styling to the material design library snackbar component.
This completes the create qr page but there is one piece still missing. Checking the create-qr.component.ts
file, it will show an error regarding the missing piece. The missing piece to this puzzle is the RestutilService
which is responsible for fetching the qr code image from the third-party API.
In the terminal, change the current directory to services, type ng g s restutil
and press enter. This will create the RestUtilService files, open the restutil.service.ts
file and add this snippet:
private edgeSize = '300';
private BASE_URL = 'https://api.qrserver.com/v1/create-qr-code/?data={data}!&size={edge}x{edge}';
constructor(private httpClient: HttpClient) { }
public getQRCode(text: string): Observable {
// Create the url with the provided data and other options
let url = this.BASE_URL;
url = url.replace("{data}", text).replace(/{edge}/g, this.edgeSize);
// Make the http api call to the url
return this.httpClient.get(url, {
responseType: 'blob'
});
}
The above service fetches the qr image from the third party API and since the response is not of json type, but an image, so we specify the responseType
as ‘blob’
in the above snippet.
Angular provides HttpClient
class to communicate with any HTTP supporting server. It provides many features like filtering the request before it is fired, getting back the response, enabling the processing of the response via callbacks and others. To use the same, add an entry for HttpClientModule
in app.module.ts
file.
Finally, import this service in the create-qr.component.ts
file to complete the create.
There is a problem with the above create qr logic. If the user uses the same text to generate the QR again and again, it will result in a network call. One way to redress this is caching the request based, thus serving the response from the cache if the request text is same.
Caching Request
Angular provides a simplified way of making HTTP calls, HttpClient, along with HttpInterceptors to inspect and transform HTTP requests or responses to and from servers. It can be used for authentication or caching and many such things, multiple interceptors can be added and chained for further processing. In this case, we are intercepting requests and serving the response from the cache if the qr text is same.
Create an interceptor folder, then create a file cache-interceptor.ts
:
Add the below code snippet to the file:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpResponse, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { tap } from 'rxjs/operators';
import { of, Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class RequestCachingService implements HttpInterceptor {
private cacheMap = new Map<string, HttpResponse>();
constructor() { }
intercept(req: HttpRequestnext: HttpHandler): Observable<HttpEvent> {
const cachedResponse = this.cacheMap.get(req.urlWithParams);
if (cachedResponse) {
return of(cachedResponse);
}
return next.handle(req).pipe(tap(event => {
if (event instanceof HttpResponse) {
this.cacheMap.set(req.urlWithParams, event);
}
}))
}
}
In the above code snippet, we have a map with the key being the request URL, and the response as the value. We check if the current URL is present in the map; if it is, then return the response (the rest is handled automatically). If the URL is not in the map, we add it.
We are not done yet, an entry to the app.module.ts
is required for its proper functioning. Add below snippet:
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { CacheInterceptor } from './interceptor/cache-interceptor';
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true }
],
This adds the caching feature to our application. Let’s move on to the third page, History page.
Adding History Page
All the saved QR codes will be visible here. To create another component, open terminal type ng g c history
and press enter.
Open history.component.css
and add the below code:
.main-content {
padding: 5% 10%;
}
.truncate {
width: 90%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.center-img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
}
Open history.component.html
and replace the content with this:
0">
{{qr.text}}
Nothing to see here
As usual, we have the header component at the top. Then the rest of the body is a grid list that will show all the saved QR codes as individual mat-card
. For the grid view, we are using mat-grid-list
from the angular material library. As per the drill, before we can use it, we have to first add it to the app.module.ts
file.
Mat grid list acts as a container with multiple tile children called mat-grid-tile
in the above html snippet, each tile is created using mat-card
using some of its properties for generic placement of other UI elements. We can provide the number of columns
and rowHeight
which is used to calculate width automatically. In the above snippet we are providing both the number of columns and the rowHeight
value.
We are using a placeholder image when the history is empty, download it and add to the assets folder.
To implement the logic for populating all these information, open history.component.ts
file and add the below snippet in the HistoryComponent class:
showBackButton = true;
title = 'History';
showHistoryNav = false;
historyList;
constructor(private storageService: StorageutilService,
private snackbar: MatSnackBar ) { }
ngOnInit() {
this.populateHistory();
}
private populateHistory() {
this.historyList = this.storageService.readAllHistory();
}
delete(text: string) {
this.storageService.deleteHistory(text);
this.populateHistory();
}
share(text: string) {
this.snackbar.open(text, '', {duration: 2000,})
}
The above logic just fetches all the saved QR and populates the page with it. Users can delete the saved QR which will delete the entry from the local storage. This finishes off our history component or does it? We need to add the route mapping for this component, open app-routing.module.ts
and add a mapping for the history page as well:
{ path: 'history', component: HistoryComponent },
The whole route array should look like this by now:
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'create', component: CreateQrComponent },
{ path: 'history', component: HistoryComponent },
];
It is a good time to run the application to check the complete flow, open terminal and type ng serve
and press enter, go to localhost:4200
to verify the working of the application.
Add To Github
Before proceeding to the deployment step, it would be good to add the project to a Github repository.
- Open Github
- Create a new repository
- In VS Code use the terminal and follow the first set of commands mentioned in the quick start guide to push all the project files
Just refresh the page to check if all the files are visible. From this point any git changes such as commit, pull/push will be reflected in this newly created repository.
Netlify & Deployment
Our application runs in our local machine, but to enable others to access it, we should deploy it on a cloud platform and register it to a domain name. This is where Netlify comes into play. It provides continuous deployment services, integration with Github and many more features to benefit from. Right now, we want to enable global access to our application, let’s get started.
- Sign-up on Netlify.
- From the dashboard, click on New site from Git button.
- Click on Github in the next screen.
- Authorize Netlify to be able to access your Github repositories.
- Search for and select the newly created
qr
repository. - Netlify, in the next step, allows us to choose the Github repository branch for deployments. Normally one uses the
master
branch but one can also have a separaterelease
branch which contains only release related and stable features.
Since, this is an angular web application, add ng build --prod
as the build command. Publish directory will be dist/qr
as mentioned in the angular.json
file.
Now click on the Deploy site
button which will trigger a project build with the command ng build --prod
and will output the file to dist/qr
.
Since we provided the path information to Netlify, it will automatically pick up the correct files for servicing the web application. Netlify adds a random domain to our application by default.
You can click on the link provided in the above page, to access our application from anywhere. Finally, our application is deployed.
Custom Domain
In the above image, the URL for our application is shown, the sub-domain is randomly generated. Let’s change it. Click on Domain settings
button then in the custom domains section click on the 3-dot menu and select Edit site name
.
This will open a popup wherein a new site name can be entered, this name should be unique across the Netlify domain. Enter any site name, which is available and click save.
Now the link to our application will be updated with the new site name.
Split Testing
Another cool feature offered by Netlify is split testing, it enables traffic splitting so that different sets of users will interact with different application deployments. We can have new features added to a different branch and split the traffic to this branch deployment, analyze traffic and then merge the feature branch with the main deployment branch. Let’s configure it.
The prerequisite to enabling split testing is a Github repository with at least two branches. Head over to the app repository in Github, created earlier, create a new branch, a
.
The repository will now have a master
branch and a
branch. Netlify needs to be configured to do branch deployments, open Netlify dashboard and click on Settings
on the left side click on Build & Deploy
then Continuous Deployment
then on the right side in the Deploy contexts
section, click on Edit settings
.
In the Branch deploys
sub-section select the option Let me add individual branches
and enter the branch names and save it.
Branch deploy is another useful feature provided by Netlify, we can select which Github repository branches to deploy, we can also enable preview for every pull request to the master
branch before merging. This is a neat feature enabling developers to actually test their changes out live before adding their code changes to the main deployment branch.
Now, click on Split Testing
tab option at the top of the page, the split testing configurations will be presented here.
We can select the branch, other than the production branch, in this case a
. We can also play around with the settings of splitting traffic, based on the traffic percentage each branch has been allotted, Netlify will re-route some users to the application deployed using a
branch and others to the master branch
. After configuring, click on Start test
button to enable traffic splitting.
TIP: Netlify may not recognize that the connected Github repository has more than one branch and may give this error:
To resolve this, just reconnect to the repository from the Build & Deploy
options.
Netlify provides a lot of other features as well, we just went through some of its useful features to demonstrate the ease of configuring different aspects of Netlify.
This brings us to the end of our journey, we have successfully created an Angular Material design based web application and deployed it on Netlify.
Conclusion
Angular is a great and popular framework for web application development, with the official Angular material design library it is much easier to create applications which adhere to the material design specs for a very natural interaction with the users. Moreover, the application developed with a great framework should use a great platform for deployment, Netlify is just that. With constant evolution, great support and with a plethora of features it surely is a great platform to bring web applications or static sites to the masses. Hopefully, this article will provide help in getting started with new Angular project from just a thought to deployment.
Next Steps
Source link