Tutorial Angular 6: Caracteristici noi cu putere nouă

Publicat: 2022-03-11

Angular 6 a ieșit! Cele mai remarcabile modificări sunt în CLI-ul său și în modul în care serviciile sunt injectate. Dacă doriți să scrieți prima dvs. aplicație Angular 6 - sau aplicația Angular/Firebase - în acest tutorial, vom trece peste pașii de bază ai configurării inițiale și vom crea o mică aplicație de jurnal.

Angular 6: Elementele de bază

Dacă nu ați mai folosit niciodată Angular, permiteți-mi să vă fac o scurtă descriere a acestuia și a modului în care funcționează.

Angular este un cadru JavaScript conceput pentru a sprijini construirea de aplicații cu o singură pagină (SPA) atât pentru desktop, cât și pentru mobil.

Cadrul include o suită completă de directive și module care vă permit să implementați cu ușurință unele dintre cele mai comune scenarii pentru o aplicație web, cum ar fi navigarea, autorizarea, formularele și raportarea. De asemenea, vine cu toate pachetele necesare pentru a adăuga teste folosind framework-ul Jasmine și a le rula folosind rulații de testare Karma sau Protractor.

Arhitectura unghiulară se bazează pe componente, șabloane, directive și servicii. Acesta oferă un mecanism de injectare a dependenței încorporat pentru serviciile dvs., precum și legare bidirecțională a datelor pentru a vă conecta vizualizările cu codul componentei.

Angular folosește TypeScript, un superset tip JS, și va face unele lucruri mai ușoare, mai ales dacă veniți dintr-un fundal de limbaj tastat.

Angular 6: Caracteristici noi

Un scurt rezumat al noilor funcții din Angular 6:

  • O politică de sincronizare a numerelor majore de versiune pentru pachetele cadru ( @angular/core , @angular/common , @angular/compiler , etc.), CLI, Material și CDK. Acest lucru va ajuta la clarificarea compatibilității încrucișate în viitor: puteți spune dintr-o privire rapidă la numărul versiunii dacă pachetele de chei sunt compatibile între ele.
  • Noi comenzi ng CLI:
    • ng update pentru a actualiza inteligent versiunile pachetelor, actualizând versiunile dependențelor și păstrându-le sincronizate. (De exemplu, când rulați ng update @angular/core , toate cadrele vor fi actualizate, precum și RxJS.) Va rula și scheme dacă pachetul le include. (Dacă o versiune mai nouă include modificări care necesită modificări ale codului, schema vă va actualiza codul.)
    • ng add pentru a adăuga pachete noi (și rulați scripturi, dacă este cazul)
  • Serviciile fac referire acum la modulele care le vor furniza, în loc de modulele care fac referire la servicii, așa cum le aveau înainte.

Ca exemplu a ceea ce înseamnă această ultimă modificare, unde arăta codul dvs.:

 @NgModule({ // ... providers: [MyService] })

… cu această schimbare specială în Angular 6, va arăta astfel:

 @Injectabe({ providedIn: 'root', })

Aceștia se numesc furnizori tree-shakeable și permit compilatorului să elimine servicii fără referință, rezultând pachete de dimensiuni mai mici.

Angular 6 CLI

Interfața de linie de comandă ng este o piesă foarte importantă a Angular și vă permite să vă mișcați mai rapid atunci când vă codificați aplicația.

Cu ajutorul CLI, puteți configura foarte ușor configurația inițială a aplicației, puteți genera noi componente, directive etc. și puteți construi și rula aplicația în mediul dvs. local.

Crearea unui proiect Angular 6

Bine, destulă vorbă. Să ne murdărim mâinile și să începem să codificăm.

Pentru a începe, veți avea nevoie de Node.js și npm instalate pe computer.

Acum, să mergem mai departe și să instalăm CLI:

 npm install -g @angular/cli

Aceasta va instala comanda ng CLI la nivel global, datorită comutatorului -g .

Odată ce avem asta, putem obține schela inițială pentru aplicația noastră cu ng new :

 ng new my-memories --style=scss

Aceasta va crea un folder my-memories , va crea toate fișierele necesare pentru a pregăti configurarea inițială pentru a începe și va instala toate pachetele necesare. --style=scss este opțional și va configura compilatorul pentru a compila fișiere SCSS în CSS, de care vom avea nevoie mai târziu.

Odată ce instalarea este finalizată, puteți să cd my-memories și să rulați ng serve . Acest lucru va începe procesul de construire și un server web local care deservește aplicația dvs. la http://localhost:4200 .

O aplicație Angular 6 imediat după schele

Ceea ce se întâmplă în culise este că CLI transpilează toate fișierele .ts (fișiere TypeScript) în vanilla JS, adună toate dependențele necesare din folderul de pachete node_modules și redă rezultatul într-un set de fișiere care sunt servite printr-un server web local. care rulează pe portul 4200.

Fișiere de proiect

Dacă nu sunteți familiarizat cu structura folderului de proiect din Angular, cel mai important lucru pe care trebuie să-l știți este că tot codul legat de aplicație intră în folderul src . De obicei, veți crea toate modulele și directivele în acel folder, urmând arhitectura aplicației (de exemplu, utilizator, coș, produs.)

Structura folderului de proiect Angular 6

Configurare inițială

Bine, până acum avem configurarea inițială pentru aplicația noastră. Să începem să facem câteva modificări.

Înainte de a începe, să pătrundem puțin în folderul src . Pagina inițială este index.html :

 <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>MyMemories</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> </head> <body> <app-root></app-root> </body> </html>

Aici vedem câteva coduri HTML de bază și eticheta <app-root> . Aceasta este o componentă Angular și unde Angular 6 inserează codul nostru de componentă.

Vom găsi fișierul app/app.component.ts , care are selectorul app-root pentru a se potrivi cu ceea ce este în fișierul index.html .

Componenta este o clasă TypeScript decorată și, în acest caz, conține proprietatea title . Decoratorul @Component îi spune lui Angular să includă comportamentul componentei în clasă. În plus față de selector, specifică ce fișier HTML să fie randat și ce foi de stil să folosească.

 import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { title = 'app'; }

Dacă ne uităm la app.component.html , vom vedea legarea de interpolare {{title}} . Aici se întâmplă toată legarea magică, iar Angular va reda valoarea proprietății titlului clasei și o va actualiza de fiecare dată când se schimbă.

 <!--The content below is only a placeholder and can be replaced.--> <div> <h1> Welcome to {{ title }}! </h1> <img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg=="> </div> <h2>Here are some links to help you start: </h2> <ul> <li> <h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2> </li> <li> <h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2> </li> <li> <h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2> </li> </ul>

Să mergem mai departe și să actualizăm title din clasă la 'My Memories!' .

 ... export class AppComponent { title = 'My Memories!'; } ...

Vom vedea cum compilatorul procesează modificarea noastră și reîmprospătează browserul pentru a afișa titlul nostru actualizat.

Aceasta înseamnă că Angular 6 ng serve ceasuri pentru modificările fișierelor noastre și se redă de fiecare dată când o modificare este introdusă în orice fișier.

Pentru a face codarea mai prietenoasă și pentru a evita reîmprospătarea completă a paginii de fiecare dată când facem modificări, putem profita de Webpack Hot Module Replacement (HMR), care actualizează doar porțiunea de JS/CSS care a fost schimbată în loc să producă o reîmprospătare completă la arată modificările tale.

Configurarea HMR

În primul rând, trebuie să creăm mediul.

Creați un fișier src/environments/environment.hmr.ts cu următorul conținut:

 export const environment = { production: false, hmr: true };

Actualizați src/environments/environment.prod.ts și adăugați hmr: false flag la mediu:

 export const environment = { production: true, hmr: false };

Apoi actualizați src/environments/environment.ts și adăugați și hmr: false flag la mediu acolo:

 export const environment = { production: false, hmr: false };

În continuare, în fișierul angular.json , actualizați această parte:

 "projects": { "my-memories": { // ... "architect": { "build": { // ... "configurations": { "hmr":{ "fileReplacements":[ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.hmr.ts" } ] }, // ...

Și sub projectsmy-memoriesarchitectserveconfigurations :

 "projects": { "my-memories": { "architect": { // ... "serve": { // ... "configurations": { "hmr": { "browserTarget": "my-memories:build:hmr" }, // ...

Acum actualizați tsconfig.app.json pentru a include types necesare (ei bine, tastați) adăugând acest lucru sub compilerOptions :

 "compilerOptions": { // ... "types": [ "node" ]

În continuare, vom instala @angularclass/hmr ca dependență de dezvoltare:

 npm install --save-dev @angularclass/hmr

Apoi configurați-l prin crearea unui fișier src/hmr.ts :

 import { NgModuleRef, ApplicationRef } from '@angular/core'; import { createNewHosts } from '@angularclass/hmr'; export const hmrBootstrap = (module: any, bootstrap: () => Promise<NgModuleRef<any>>) => { let ngModule: NgModuleRef<any>; module.hot.accept(); bootstrap().then(mod => ngModule = mod); module.hot.dispose(() => { const appRef: ApplicationRef = ngModule.injector.get(ApplicationRef); const elements = appRef.components.map(c => c.location.nativeElement); const makeVisible = createNewHosts(elements); ngModule.destroy(); makeVisible(); }); };

Apoi, actualizați src/main.ts pentru a utiliza funcția de mai sus:

 import { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; import { hmrBootstrap } from './hmr'; if (environment.production) { enableProdMode(); } const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule); if (environment.hmr) { if (module[ 'hot' ]) { hmrBootstrap(module, bootstrap); } else { console.error('HMR is not enabled for webpack-dev-server!'); console.log('Are you using the --hmr flag for ng serve?'); } } else { bootstrap().catch(err => console.log(err)); }

Ceea ce facem aici este să facem apelul bootstrap să fie o funcție anonimă și apoi să întrebăm dacă indicatorul environment.hmr este adevărat. Dacă este, apelăm funcția definită anterior din hmr.ts care a permis înlocuirea la cald a modulului; în caz contrar, îl pornim așa cum obișnuiam.

Acum, când rulăm ng serve --hmr --configuration=hmr , vom invoca configurația hmr , iar când vom face modificări la fișiere, vom primi actualizări fără o reîmprospătare completă. Primul --hmr este pentru webpack și --configuration=hmr este pentru Angular să folosească mediul hmr .

Aplicație web progresivă (PWA)

Pentru a adăuga suport pentru Angular 6 PWA și pentru a activa încărcarea offline pentru aplicație, putem folosi una dintre noile comenzi CLI, ng add :

 ng add @angular/[email protected]

Rețineți că adaug versiunea, deoarece cea mai recentă versiune când scriam acest tutorial prezenta o eroare. (Puteți încerca fără el și verificați dacă funcționează pentru dvs. folosind pur și simplu ng add @angular/pwa .)

Bine, așa că după ce vom rula comanda, vom vedea o mulțime de modificări în proiectul nostru. Cele mai importante modificări sunt că a adăugat:

  • O referință la manifest.json în fișierul de active angular.json , astfel încât să fie inclus în rezultatul build-ului, precum și "serviceWorker": true în versiunile de producție
  • Fișierul ngsw-config.json cu configurarea inițială pentru a stoca în cache toate fișierele necesare pentru rularea aplicației
  • O metaetichetă manifest.json în fișierul index.html
  • Fișierul manifest.json în sine, cu o configurație de bază pentru aplicație
  • Încărcarea lucrătorului de service în modulul de aplicație ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production }) (rețineți că lucrătorul de service va fi activat numai în mediile de producție)

Deci, aceasta înseamnă că atunci când utilizatorul accesează pentru prima dată adresa URL, fișierele vor fi descărcate. După aceea, dacă utilizatorul încearcă să acceseze adresa URL fără serviciu de rețea, aplicația va funcționa în continuare prin extragerea acelor fișiere din cache.

Adăugarea bibliotecii Material Angular 6 UI

Până acum avem configurația inițială și suntem gata să începem construirea aplicației noastre. Pentru a folosi componentele deja construite, putem folosi versiunea Angular 6 a Material.

Pentru a instala pachetul de material în aplicația noastră, vom folosi din nou ng add :

 ng add @angular/material

După ce vom rula asta, vom vedea câteva pachete noi adăugate și o configurație de bază a stilului:

  • index.html include fontul Roboto și pictogramele Material
  • BrowserAnimationsModule este adăugat la AppModule
  • angular.json are deja inclusă tema indigo-roz pentru noi

Indicând alegerea dvs. pentru o temă Angular 6 preconstruită

Va trebui să reporniți ng serve pentru a prelua tema sau puteți alege o altă temă predefinită.

Înrudit: Construiți aplicații web ultramoderne cu material unghiular

Aspect de bază

Pentru a avea aspectul sidenav inițial, vom folosi schemele care vin cu Material. Dar este în regulă dacă doriți să utilizați un aspect diferit.

(Pe scurt, schemele vă permit să aplicați transformări unui proiect: puteți să creați, să modificați sau să ștergeți fișiere după cum este necesar. În acest caz, schelele un aspect sidenav pentru aplicația noastră.)

 ng generate @angular/material:material-nav --name=my-nav

Aceasta va crea o componentă sidenav cu configurarea minimă gata de pornire. Nu este grozav?

De asemenea, a inclus toate modulele necesare în app.module.ts .

O componentă Angular 6 „my-nav” nou creată

Deoarece folosim SCSS, trebuie să redenumim fișierul my- my-nav.component.css în my-nav.component.scss , iar în my-nav.component.ts actualizăm styleUrls de referință corespunzătoare pentru a utiliza noul nume.

Acum, pentru a folosi noua componentă, să mergem la app.component.html și să eliminăm tot codul inițial, lăsând doar:

 <app-my-nav></app-my-nav>

Când ne întoarcem la browser, iată ce vom vedea:

Un aspect cu patru panouri cu Meniu în colțul din stânga sus, amintirile mele lângă el și trei link-uri numerotate sub Meniu; al patrulea panou este gol

Să actualizăm linkurile pentru a avea doar cele două opțiuni pe care le dorim.

Mai întâi, să creăm două componente noi:

 ng gc AddMemory ng generate @angular/material:material-table --name=view-memories

(A doua este o schemă de material folosită pentru a crea un tabel.)

Apoi, pe my-nav ne vom actualiza pentru a configura legăturile și vom include <router-outlet> pentru a afișa componentele noastre de conținut:

 <mat-sidenav-container class="sidenav-container"> <mat-sidenav #drawer class="sidenav" fixedInViewport="true" [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'" [mode]="(isHandset$ | async) ? 'over' : 'side'" [opened]="!(isHandset$ | async)"> <mat-toolbar color="primary">Menu</mat-toolbar> <mat-nav-list> <a mat-list-item [routerLink]="['/add-memory']">Add Memory</a> <a mat-list-item [routerLink]="['/view-memories']">View My Memories</a> </mat-nav-list> </mat-sidenav> <mat-sidenav-content> <mat-toolbar color="primary"> <button type="button" aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()" *ngIf="isHandset$ | async"> <mat-icon aria-label="Side nav toggle icon">menu</mat-icon> </button> <span>my-memories</span> </mat-toolbar> <router-outlet></router-outlet> </mat-sidenav-content> </mat-sidenav-container>

De asemenea, în app.component.html trebuie să-l actualizăm pentru a avea doar <router-outlet> principal (adică, eliminați <my-nav> ):

 <router-outlet></router-outlet>

În continuare, în AppModule vom include rutele:

 import { RouterModule, Routes } from '@angular/router'; // ... imports: [ // ... RouterModule.forRoot([ { path: '', component: MyNavComponent, children: [ { path: 'add-memory', component: AddMemoryComponent }, { path: 'view-memories', component: ViewMemoriesComponent } ] }, ]), ]

Rețineți că MyNavComponent ca părinte și cele două componente pe care le-am creat ca copii. Acest lucru se datorează faptului că am inclus <router-outlet> în MyNavComponent și de fiecare dată când atingem una dintre aceste două rute, vom reda componenta copil în care a fost plasat <router-outlet> .

După aceasta, când servim aplicația, ar trebui să vedem:

Legăturile din stânga au fost înlocuite cu Adăugați memorie și Vizualizați amintirile mele, acestea din urmă fiind selectate. Panoul gol are acum un tabel cu numere și nume de identificare.

Creați aplicația (A Memories Diary)

Bine, acum să creăm formularul pentru a salva noi amintiri în jurnalul nostru.

Va trebui să importăm câteva module de materiale și modulul de formulare în app.module.ts :

 import { FormsModule } from '@angular/forms'; import { MatCardModule, MatFormFieldModule, MatInputModule, MatDatepickerModule, MatNativeDateModule } from '@angular/material'; // ... Imports:[ // ... MatCardModule, MatFormFieldModule, MatInputModule, MatDatepickerModule, FormsModule, MatNativeDateModule, // ... ]

Și apoi în add-memory.component.html , vom adăuga forma:

 <form #form="ngForm" (ngSubmit)="onSubmit()"> <mat-card class="memory-card"> <mat-card-title> Add a memory </mat-card-title> <mat-card-content> <mat-form-field> <input disabled matInput placeholder="Select the date..." [(ngModel)]="memory.date" name="date" [matDatepicker]="date"> <mat-datepicker-toggle matSuffix [for]="date"></mat-datepicker-toggle> <mat-datepicker disabled="false" #date></mat-datepicker> </mat-form-field> <mat-form-field> <textarea placeholder="Enter your memory..." rows="3" maxlength="300" matInput [(ngModel)]="memory.text" name="memory"></textarea> </mat-form-field> </mat-card-content> <mat-card-actions> <button mat-button type="submit">Save me!</button> </mat-card-actions> </mat-card> </form> <pre> {{ memory | json }} </pre>

Aici folosim un mat-card și adăugăm două câmpuri, o date și o zonă de textarea .

Rețineți că folosim [(ngModel)] . Această directivă Angular va lega expresia memory.date și proprietatea memory din clasă una de cealaltă, așa cum vom vedea mai târziu. ( [(ngModel)] este zahăr sintactic — o comandă rapidă pentru a efectua legături bidirecționale de date de la clasă la vizualizare și de la vizualizare la clasă. Aceasta înseamnă că atunci când introduceți text în vizualizare, memory.date va reflecta acele modificări în instanța de clasă și dacă faceți modificări la memory.date în instanța de clasă, vizualizarea va reflecta modificările.)

În add-memory.component.ts , codul va arăta astfel:

 import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-add-memory', templateUrl: './add-memory.component.html', styleUrls: ['./add-memory.component.scss'] }) export class AddMemoryComponent implements OnInit { memory: any = {}; constructor() { } ngOnInit() { } onSubmit() { console.log(this.memory); } }

Aici, inițializam proprietatea memory legată de ngModel . Când componenta AddMemoryComponent este instanțiată, memory va fi un obiect gol. Apoi, când se rulează directiva ngModel , va putea atribui valoarea de intrare memory.date și memory.text . Dacă nu am face acest lucru, vom primi o eroare de Cannot set property 'date/text' of undefined .

Între timp, add-memory.component.scss trebuie să aibă:

 .memory-card { min-width: 150px; max-width: 400px; width: 100%; margin: auto; } .mat-form-field { width: 100%; }

Deoarece avem <pre> {{ memory | json }} </pre> <pre> {{ memory | json }} </pre> putem vedea starea curentă a memory în vizualizare. Dacă mergem la browser, iată rezultatul de până acum:

Prototipul aplicației jurnal „my-memories”, care arată reprezentarea internă a intrărilor utilizatorului (data și text.)

În vizualizare, am legat formularul prin (ngSubmit)="onSubmit()" la funcția onSubmit din clasă.

 onSubmit() { console.log(this.memory); }

Deci, când dați clic pe „Salvați-mă!” butonul, veți primi reprezentarea internă a intrării utilizatorului trimisă în jurnalul consolei:

Reprezentarea internă a intrării utilizatorului în jurnalul consolei.

Tutorial Angular 6: Conectarea cu Firebase

Ceea ce vom face în continuare este să ne conectăm proiectul la Firebase pentru a ne salva amintirile.

Mai întâi, vom merge la consola Firebase și vom crea un proiect acolo.

Adăugarea unui proiect Firebase.

În al doilea rând, vom instala pachetele firebase și angularfire2 :

 npm install firebase angularfire2 --save

Și apoi în fiecare dintre aceste trei fișiere:

  1. /src/environments/environment.ts
  2. /src/environments/environment.hmr.ts
  3. /src/environments/environment.prod.ts

… vom adăuga configurația noastră Firebase:

 export const environment = { // ... firebase: { apiKey: '<your-key>', authDomain: '<your-project-authdomain>', databaseURL: '<your-database-URL>', projectId: '<your-project-id>', storageBucket: '<your-storage-bucket>', messagingSenderId: '<your-messaging-sender-id>' } };

Puteți obține detaliile de configurare necesare pentru fișierele de mai sus făcând clic pe „Adăugați Firebase la aplicația dvs. web” pe pagina de prezentare generală a proiectului.

După aceea, vom include modulele Firebase în app.module.ts :

 import { AngularFireModule } from 'angularfire2'; import { AngularFireDatabaseModule } from 'angularfire2/database'; import { environment } from '../environments/environment'; // ... Imports:[ // ... AngularFireModule.initializeApp(environment.firebase), AngularFireDatabaseModule, // ... ]

Și în add-memory.component.ts , injectăm baza de date în constructor și salvăm valorile din formular în baza de date. Când promisiunea push de la Firebase are succes, înregistrăm succesul în consolă și resetam modelul:

 import { AngularFireDatabase } from 'angularfire2/database'; // ... constructor(private db: AngularFireDatabase) { } // ... onSubmit() { this.memory.date = new Date(this.memory.date).valueOf(); this.db.list('memories').push(this.memory) .then(_ => { this.memory = {} console.log('success') }) } 

Permiterea accesului de citire și scriere la baza de date Firebase.

Va trebui să permiteți accesul public la regulile bazei de date, astfel încât utilizatorii anonimi să poată citi și scrie în ea. Vă rugăm să rețineți că, cu această configurare, orice utilizator va putea citi/modifica/șterge datele aplicației dvs. Asigurați-vă că vă configurați regulile în consecință înainte de a trece la producție.

De asemenea, pentru a prelua schimbările de mediu, va trebui să reporniți procesul ng serve .

Acum, când ne întoarcem la browser și facem clic pe butonul de salvare, vom vedea că memoria a fost adăugată la baza de date:

Memoria noastră de testare a fost adăugată la baza de date Firebase a aplicației noastre de jurnal.

Să aruncăm o privire la modul în care ne putem recupera amintirile și le putem afișa în tabelul Material.

Când am creat tabelul folosind ng generate @angular/material:material-table --name=view-memories', we automatically got a file view-memories/view-memories-datasource.ts`. Acest fișier conține date false, așa că va trebui să-l modificăm pentru a începe extragerea din Firebase.

În view-memories-datasource.ts , vom elimina EXAMPLE_DATA și vom seta o matrice goală:

 export class ViewMemoriesDataSource extends DataSource<ViewMemoriesItem> { data: ViewMemoriesItem[] = []; // ...

Și în getSortedData vom actualiza numele câmpurilor:

 private getSortedData(data: ViewMemoriesItem[]) { if (!this.sort.active || this.sort.direction === '') { return data; } return data.sort((a, b) => { const isAsc = this.sort.direction === 'asc'; switch (this.sort.active) { case 'text': return compare(a.name, b.name, isAsc); case 'date': return compare(+a.id, +b.id, isAsc); default: return 0; } }); }

În view-memories.component.html vom actualiza numele coloanelor la date și text din modelul nostru de memorie. Rețineți că, deoarece am salvat data în format de milisecunde, aici folosim un canal de dată pentru a transforma valoarea pentru afișare într-un format de dată mai prietenos cu oamenii. În cele din urmă, eliminăm [length]="dataSource.data.length" din paginator, deoarece vom încărca datele asincron din Firebase:

 <div class="mat-elevation-z8"> <table mat-table #table [dataSource]="dataSource" matSort aria-label="Elements"> <!-- Id Column --> <ng-container matColumnDef="date"> <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th> <td mat-cell *matCellDef="let row">{{row.date | date:'short'}}</td> </ng-container> <!-- Name Column --> <ng-container matColumnDef="text"> <th mat-header-cell *matHeaderCellDef mat-sort-header>Text</th> <td mat-cell *matCellDef="let row">{{row.text}}</td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table> <mat-paginator #paginator [pageIndex]="0" [pageSize]="50" [pageSizeOptions]="[25, 50, 100, 250]"> </mat-paginator> </div>

Schimbați view-memories.component.css în view-memories.component.scss și setați stilul tabelului:

 table{ width: 100%; }

În view-memories.component.ts , vom schimba styleUrls pentru a reflecta redenumirea de mai sus în ./view-memories.component.scss . De asemenea, vom actualiza matricea displayedColumns pentru a fi ['date', 'text'] și vom configura sursa de date din tabel pentru a obține date de la Firebase.

Ceea ce se întâmplă aici este că ne abonam la lista de memorii și când primim datele, instanțiăm ViewMemoriesDataSource și setăm proprietatea de date cu datele din Firebase.

 this.subscription = this.db.list<ViewMemoriesItem>('memories').valueChanges().subscribe(d=>{ console.log('data streaming'); this.dataSource = new ViewMemoriesDataSource(this.paginator, this.sort); this.dataSource.data = d; });

Firebase returnează o matrice Observable în stil ReactiveX.

Rețineți că this.db.list<ViewMemoriesItem>('memories') — valorile extrase din calea 'memories' — în ViewMemoriesItem . Acest lucru este îngrijit de biblioteca angularfire2 .

Am inclus și apelul de unsubscribe în hook-ul onDestroy al ciclului de viață al componentei Angular.

 import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core'; import { MatPaginator, MatSort } from '@angular/material'; import { ViewMemoriesDataSource, ViewMemoriesItem } from './view-memories-datasource'; import { AngularFireDatabase } from 'angularfire2/database'; import { Subscription } from 'rxjs'; import { map, first } from 'rxjs/operators'; @Component({ selector: 'app-view-memories', templateUrl: './view-memories.component.html', styleUrls: ['./view-memories.component.scss'] }) export class ViewMemoriesComponent implements OnInit, OnDestroy{ @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; dataSource: ViewMemoriesDataSource; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['date', 'text']; subscription: Subscription; constructor(private db: AngularFireDatabase) { } ngOnInit() { this.subscription = this.db.list<ViewMemoriesItem>('memories').valueChanges().subscribe(d=>{ console.log('data streaming'); this.dataSource = new ViewMemoriesDataSource(this.paginator, this.sort); this.dataSource.data = d; }); } ngOnDestroy(): void { this.subscription.unsubscribe(); } }
Înrudit: Construirea de aplicații mobile în timp real, cu mai multe platforme: exemple folosind Ionic Framework și Firebase

Implementare pe Firebase Hosting

Acum, pentru a face aplicația noastră live, să o implementăm pe Firebase Hosting. Pentru aceasta, vom instala CLI-ul Firebase, care face disponibilă comanda firebase :

 npm install -g firebase-tools

Acum putem folosi Firebase CLI pentru a vă conecta:

 firebase login

Acest lucru vă va solicita să vă selectați contul Google.

În continuare, vom inițializa proiectul și vom configura Firebase Hosting:

 firebase init

Vom selecta doar opțiunea Gazduire.

Apoi, când ni se cere calea, o vom seta la dist/my-memories . Când suntem întrebați dacă o configuram ca aplicație cu o singură pagină (adică rescriem toate adresele URL în /index.html ), vom răspunde „da”.

În cele din urmă, vom apăsa „File dist/my-memories/index.html deja există. Suprascrie?” Aici vom spune „nu”.

Aceasta va crea fișierele de configurare Firebase .firebaserc și firebase.json cu configurația furnizată.

Ultimul pas este să rulați:

 ng build --prod firebase deploy

Și cu asta, vom fi publicat aplicația în Firebase, care oferă o adresă URL la care să navigăm, cum ar fi https://my-memories-b4c52.firebaseapp.com/view-memories, unde puteți vedea propria mea publicată demonstrație.


Wow, ai trecut prin tutorial! Sper ca ti-a placut. De asemenea, puteți consulta codul complet al acestuia pe GitHub.

Cu pasi marunti

Angular este un cadru foarte puternic pentru construirea de aplicații web. A existat de mult timp și s-a dovedit atât pentru aplicațiile mici, simple, cât și pentru cele mari și complexe — Angular 6 nu face excepție aici.

În continuare, Angular intenționează să continue să se îmbunătățească și să urmeze noi paradigme web, cum ar fi componentele web (Angular Elements). Dacă sunteți interesat să construiți aplicații hibride, puteți verifica Ionic, care folosește Angular ca cadru de bază.

Acest tutorial a acoperit pașii de bază pentru a începe să utilizați Angular, Material și Firebase. Dar ar trebui să țineți cont de faptul că, pentru aplicațiile din lumea reală, va trebui să adăugați validare și, pentru a face aplicația mai ușor de întreținut și scalat, probabil că ați dori să urmați cele mai bune practici, cum ar fi utilizarea Serviciilor, a componentelor reutilizabile etc. Acesta va trebui să facă obiectul unui alt articol - sperăm că acesta a fost suficient pentru a vă stârni apetitul pentru dezvoltarea Angular!

Înrudit: Toate avantajele, fără bătăi de cap: Un tutorial Angular 9