Angular 6 Tutorial: Nieuwe functies met nieuwe kracht
Angular 6 is uit! De meest opvallende veranderingen zijn in de CLI en hoe services worden geïnjecteerd. Als je je eerste Angular 6 app wilt schrijven – of Angular/Firebase app – dan zullen we in deze tutorial de basisstappen van de eerste installatie doorlopen en een kleine dagboek app maken.
Angular 6: The Basics
Als je nog nooit Angular hebt gebruikt, zal ik je een korte beschrijving geven van Angular en hoe het werkt.
Angular is een JavaScript-framework dat is ontworpen om het bouwen van single-page applicaties (SPA’s) voor zowel desktop als mobiel te ondersteunen.
Het framework bevat een volledige suite van directives en modules waarmee je eenvoudig een aantal van de meest voorkomende scenario’s voor een web app kunt implementeren, zoals navigatie, autorisatie, formulieren, en rapportage. Het wordt ook geleverd met alle benodigde pakketten om tests toe te voegen met behulp van het Jasmine framework en ze uit te voeren met behulp van de Karma of Protractor test runners.
Angular architectuur is gebaseerd op componenten, templates, directives, en services. Het biedt een ingebouwd dependency injection mechanisme voor je services, evenals twee-weg data binding om je views te verbinden met je component code.
Angular maakt gebruik van TypeScript, een getypte superset van JS, en zal sommige dingen makkelijker maken, vooral als je uit een getypte taal achtergrond komt.
Angular 6: New Features
Een korte samenvatting van nieuwe features in Angular 6:
- Een beleid om belangrijke versienummers te synchroniseren voor de framework packages (
@angular/core
,@angular/common
,@angular/compiler
, etc.), CLI, Material, en CDK. Dit zal helpen om cross-compatibiliteit duidelijker te maken in de toekomst: U kunt in een oogopslag aan het versienummer zien of belangrijke pakketten compatibel met elkaar zijn. - Nieuwe
ng
CLI-commando’s:-
ng update
om pakketversies slim te upgraden, waarbij afhankelijkheidsversies worden bijgewerkt en in sync worden gehouden. (Bijv. bij het uitvoeren vanng update @angular/core
zullen alle frameworks worden bijgewerkt, evenals RxJS.) Het zal ook schema’s uitvoeren als het pakket deze bevat. (Als een nieuwere versie brekende veranderingen bevat die veranderingen in de code vereisen, zal het schema uw code voor u bijwerken.) -
ng add
om nieuwe pakketten toe te voegen (en scripts uit te voeren, indien van toepassing)
-
- Services verwijzen nu naar de modules die ze zullen leveren, in plaats van modules die naar services verwijzen, zoals vroeger het geval was.
Als voorbeeld van wat deze laatste verandering betekent, waar uw code er vroeger uitzag als:
@NgModule({ // ... providers: })
…met deze specifieke verandering in Angular 6, zal het er uitzien als:
@Injectabe({ providedIn: 'root',})
Deze worden tree-shakeable providers genoemd en stellen de compiler in staat om unreferenced services te verwijderen, wat resulteert in kleinere omvang bundels.
Angular 6 CLI
De ng
command-line interface is een zeer belangrijk onderdeel van Angular en stelt u in staat om sneller te gaan bij het coderen van uw app.
Met de CLI kunt u uw initiële app setup zeer eenvoudig scaffold, genereer nieuwe componenten, directives, etc, en bouw en draai uw app in uw lokale omgeving.
Creëren van een Angular 6 Project
Okay, genoeg gepraat. Laten we onze handen vuil maken en beginnen met coderen.
Om te beginnen, moet u Node.js en npm op uw machine geïnstalleerd hebben.
Nu, laten we doorgaan en de CLI installeren:
npm install -g @angular/cli
Dit zal het ng
CLI commando globaal installeren, als gevolg van de -g
switch.
Als we dat eenmaal hebben, kunnen we de initiële steiger voor onze app met ng new
:
ng new my-memories --style=scss
Dit zal een my-memories
map maken, alle nodige bestanden om uw initiële setup klaar te krijgen om te beginnen, en installeer alle benodigde pakketten. De --style=scss
switch is optioneel en zal de compiler instellen om SCSS bestanden te compileren naar CSS, wat we later nodig zullen hebben.
Als de installatie compleet is, kunt u cd my-memories
en ng serve
uitvoeren. Dit zal het bouwproces starten en een lokale webserver die uw app serveert op http://localhost:4200
.
Wat er achter de schermen gebeurt, is dat de CLI alle .ts
(TypeScript-bestanden) omzet naar vanilla JS, alle vereiste afhankelijkheden uit de packages-map node_modules
verzamelt en het resultaat in een set bestanden uitvoert die worden geserveerd via een lokale webserver die draait op poort 4200.
Project Files
Als u niet bekend bent met de project folder structuur van Angular, is het belangrijkste dat u moet weten dat alle code gerelateerd aan de app in de src
folder komt. Normaal gesproken maakt u al uw modules en directives in die map volgens de architectuur van uw app (bijv. gebruiker, winkelwagen, product.)
Initiële setup
Okee, tot zover hebben we de initiële setup voor onze app. Laten we beginnen met het maken van een aantal wijzigingen.
Voordat we beginnen, laten we een beetje graven in de src
map. De initiële pagina is 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>
Hier zien we wat basis HTML en de <app-root>
tag. Dit is een Angular component, en waar Angular 6 onze component code invoegt.
We vinden het app/app.component.ts
bestand, dat de selector app-root
heeft om overeen te komen met wat er in het index.html
bestand staat.
De component is een gedecoreerde TypeScript klasse, en bevat in dit geval de title
eigenschap. De @Component
-decorator vertelt Angular om het gedrag van de component in de klasse op te nemen. Naast de selector wordt gespecificeerd welk HTML-bestand moet worden gerenderd en welke stylesheets moeten worden gebruikt.
import { Component } from '@angular/core';@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: })export class AppComponent { title = 'app';}
Als we naar app.component.html
kijken, zien we de {{title}}
interpolatie-binding. Hier gebeurt alle magische binding, en Angular zal de waarde van de klasse titel eigenschap renderen en bijwerken elke keer dat het verandert.
<!--The content below is only a placeholder and can be replaced.--><div style="text-align:center"> <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>
Laten we doorgaan en update de title
van de klasse naar 'My Memories!'
.
...export class AppComponent { title = 'My Memories!';}...
We zien de compiler onze wijziging verwerken en de browser vernieuwen om onze bijgewerkte titel te tonen.
Dit betekent dat Angular 6’s ng serve
kijkt naar onze bestandswijzigingen en rendert elke keer als er een wijziging in een bestand wordt geïntroduceerd.
Om codering vriendelijker te maken en volledige paginaverversing te vermijden elke keer dat we wijzigingen aanbrengen, kunnen we profiteren van webpack Hot Module Replacement (HMR), die alleen het brok JS/CSS bijwerkt dat is gewijzigd in plaats van een volledige verversing te produceren om uw wijzigingen te tonen.
HMR configureren
Eerst moeten we de omgeving instellen.
Maak een bestand src/environments/environment.hmr.ts
met de volgende inhoud:
export const environment = { production: false, hmr: true};
Update src/environments/environment.prod.ts
en voeg de hmr: false
vlag toe aan de omgeving:
export const environment = { production: true, hmr: false};
Werk vervolgens src/environments/environment.ts
bij en voeg ook daar de hmr: false
vlag toe aan de omgeving:
export const environment = { production: false, hmr: false};
Volgende in het angular.json
bestand, update dit gedeelte:
"projects": { "my-memories": { // ... "architect": { "build": { // ... "configurations": { "hmr":{ "fileReplacements": }, // ...
En onder projects
→ my-memories
→ architect
→ serve
→ configurations
:
"projects": { "my-memories": { "architect": { // ... "serve": { // ... "configurations": { "hmr": { "browserTarget": "my-memories:build:hmr" }, // ...
Werk nu tsconfig.app.json
bij om de benodigde types
(nou ja, type) op te nemen door dit toe te voegen onder compilerOptions
:
"compilerOptions": { // ... "types":
Volgende, we zullen de @angularclass/hmr
module installeren als een ontwikkelingsafhankelijkheid:
npm install --save-dev @angularclass/hmr
Dan configureren we het door een bestand src/hmr.ts
te maken:
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(); });};
Volgende, update src/main.ts
om de bovenstaande functie te gebruiken:
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) { 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));}
Wat we hier doen is bootstrap een anonieme functie laten aanroepen, en vervolgens vragen of de environment.hmr
vlag true is. Als dat zo is, roepen we de eerder gedefinieerde functie van hmr.ts
aan die hot module replacement mogelijk maakte; anders bootstrappen we het zoals we gewend zijn.
Nu, als we ng serve --hmr --configuration=hmr
draaien, roepen we de hmr
configuratie aan, en als we wijzigingen in bestanden aanbrengen, krijgen we updates zonder een volledige refresh. De eerste --hmr
is voor webpack, en --configuration=hmr
is voor Angular om de hmr
omgeving te gebruiken.
Progressive Web App (PWA)
Om Angular 6 PWA ondersteuning toe te voegen en offline laden voor de app mogelijk te maken, kunnen we gebruik maken van een van de nieuwe CLI commando’s, ng add
:
ng add @angular/
Merk op dat ik de versie toevoeg, omdat de laatste versie toen ik deze tutorial aan het schrijven was een fout gaf. (Je kunt het zonder proberen en kijken of het voor jou werkt door simpelweg ng add @angular/pwa
te gebruiken.)
Okay, dus nadat we het commando hebben uitgevoerd, zullen we een hoop veranderingen zien in ons project. De belangrijkste veranderingen zijn dat er is toegevoegd:
- Een verwijzing naar
manifest.json
in hetangular.json
assets bestand, zodat het wordt opgenomen in de build output, evenals"serviceWorker": true
in productie builds - Het
ngsw-config.json
bestand met de initiële setup om alle bestanden te cachen die nodig zijn om de app te laten draaien - Een
manifest.json
meta tag in hetindex.html
bestand - Het
manifest.json
bestand zelf, met een basis configuratie voor de app - De service worker load in de app module
ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production })
(merk op dat de service worker alleen zal worden ingeschakeld in productie omgevingen)
Dit betekent nu dus dat wanneer de gebruiker voor het eerst de URL benadert, de bestanden zullen worden gedownload. Daarna, als de gebruiker probeert om de URL te openen zonder netwerk service, zal de app nog steeds werken door het ophalen van die cache bestanden.
Het toevoegen van de Material Angular 6 UI bibliotheek
Zo ver hebben we de initiële setup, en we zijn klaar om te beginnen met het bouwen van onze app. Om gebruik te maken van reeds gebouwde componenten, kunnen we de Angular 6 versie van Material gebruiken.
Om het material
pakket op onze app te installeren, zullen we weer gebruik maken van ng add
:
ng add @angular/material
Nadat we dat hebben uitgevoerd, zullen we een aantal nieuwe pakketten toegevoegd zien en wat basis stijl configuratie:
-
index.html
bevat het Roboto font en Material icons -
BrowserAnimationsModule
is toegevoegd aan onzeAppModule
-
angular.json
heeft het indigo-roze thema al voor ons opgenomen
U moet ng serve
opnieuw opstarten om het thema op te halen, of u kunt een ander kant-en-klaar thema kiezen.
Basic Layout
Om de initiële sidenav lay-out te hebben, zullen we de schema’s gebruiken die bij Material worden geleverd. Maar het is OK als je een andere layout wilt gebruiken.
(In een notendop, schema’s laten je transformaties toepassen op een project: U kunt bestanden maken, wijzigen of verwijderen als dat nodig is. In dit geval, het steigers een sidenav lay-out voor onze app.)
ng generate @angular/material:material-nav --name=my-nav
Dit zal een sidenav component te maken met de minimale setup klaar om te beginnen. Is dat niet geweldig?
Het heeft ook alle benodigde modules opgenomen in onze app.module.ts
.
Omdat we SCSS gebruiken, moeten we het my-nav.component.css
bestand hernoemen naar my-nav.component.scss
, en in my-nav.component.ts
de corresponderende referentie styleUrls
bijwerken om de nieuwe naam te gebruiken.
Nu om gebruik te maken van de nieuwe component, laten we naar app.component.html
gaan en alle initiële code verwijderen, zodat alleen overblijft:
<app-my-nav></app-my-nav>
Wanneer we teruggaan naar de browser, is dit wat we zullen zien:
Laten we de links bijwerken zodat ze alleen de twee opties hebben die we willen.
Maken we eerst twee nieuwe componenten:
ng g c AddMemoryng generate @angular/material:material-table --name=view-memories
(De tweede is een materiaalschema dat wordt gebruikt om een tabel te maken.)
Volgende, op my-nav
zullen we bijwerken om de links op te zetten en de <router-outlet>
op te nemen om onze inhoudscomponenten weer te geven:
<mat-sidenav-container class="sidenav-container"> <mat-sidenav #drawer class="sidenav" fixedInViewport="true" ="(isHandset$ | async) ? 'dialog' : 'navigation'" ="(isHandset$ | async) ? 'over' : 'side'" ="!(isHandset$ | async)"> <mat-toolbar color="primary">Menu</mat-toolbar> <mat-nav-list> <a mat-list-item ="">Add Memory</a> <a mat-list-item ="">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>
Ook, in app.component.html
moeten we het bijwerken om alleen de hoofd <router-outlet>
te hebben (d.w.z., <my-nav>
te verwijderen):
<router-outlet></router-outlet>
Volgende, op de AppModule
zullen we de routes opnemen:
import { RouterModule, Routes } from '@angular/router';// ...imports: }, ]),]
Merk op dat we MyNavComponent
als de ouder instellen en de twee componenten die we als kinderen hebben gemaakt. Dit komt omdat we de <router-outlet>
in MyNavComponent
hebben opgenomen, en telkens wanneer we een van deze twee routes openen, renderen we de kindcomponent waar de <router-outlet>
is geplaatst.
Wanneer we hierna de app serveren, zouden we moeten zien:
Bouw de app (Een herinneringsdagboek)
Okee, laten we nu het formulier maken om nieuwe herinneringen in ons dagboek op te slaan.
We moeten een aantal materiaal modules en de formulieren module importeren naar onze app.module.ts
:
import { FormsModule } from '@angular/forms';import { MatCardModule, MatFormFieldModule, MatInputModule, MatDatepickerModule, MatNativeDateModule } from '@angular/material';// ...Imports:
En dan in add-memory.component.html
, voegen we het formulier toe:
<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..." ="memory.date" name="date" ="date"> <mat-datepicker-toggle matSuffix ="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 ="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>
Hier gebruiken we een mat-card
en voegen we twee velden toe, een date
en een textarea
.
Noteer dat we gebruiken. Deze Angular directive zal de
memory.date
expressie en de memory
eigenschap in de klasse aan elkaar binden, zoals we later zullen zien. ( is syntactische suiker-een snelkoppeling om twee-weg data binding uit te voeren van de klasse naar de view en van de view naar de klasse. Dit betekent dat wanneer u tekst invoert in de view,
memory.date
deze veranderingen zal weergeven in de klasse-instantie, en als u wijzigingen aanbrengt in memory.date
in de klasse-instantie, zal de view de veranderingen weergeven.)
In de add-memory.component.ts
, zal de code er als volgt uitzien:
import { Component, OnInit } from '@angular/core';@Component({ selector: 'app-add-memory', templateUrl: './add-memory.component.html', styleUrls: })export class AddMemoryComponent implements OnInit { memory: any = {}; constructor() { } ngOnInit() { } onSubmit() { console.log(this.memory); }}
Hier initialiseren we de memory
property die is gebonden via ngModel
. Wanneer de AddMemoryComponent
component wordt geïnitialiseerd, zal memory
een leeg object zijn. Wanneer dan de ngModel
directief loopt, zal het in staat zijn om de invoerwaarde toe te wijzen aan memory.date
en memory.text
. Als we dit niet zouden doen, zouden we een fout krijgen van Cannot set property 'date/text' of undefined
.
Metterdaad, add-memory.component.scss
moet hebben:
.memory-card { min-width: 150px; max-width: 400px; width: 100%; margin: auto;}.mat-form-field { width: 100%;}
Omdat we <pre> {{ memory | json }} </pre>
hebben, kunnen we de huidige toestand van memory
in de view zien. Als we naar de browser gaan, zien we hier het resultaat tot nu toe:
In de view hebben we het formulier via (ngSubmit)="onSubmit()"
aan de functie onSubmit
in de klasse gebonden.
onSubmit() { console.log(this.memory); }
Dus wanneer u op de knop “Sla me op!” klikt, krijgt u de interne weergave van de gebruikersinvoer die naar de console log wordt gestuurd:
Angular 6 Tutorial: Verbinding maken met Firebase
Wat we nu gaan doen is ons project verbinden met Firebase om onze herinneringen op te slaan.
Eerst gaan we naar de Firebase console en maken daar een project aan.
Tweede installeren we de firebase
en angularfire2
pakketten:
npm install firebase angularfire2 --save
En dan in elk van deze drie bestanden:
/src/environments/environment.ts
/src/environments/environment.hmr.ts
/src/environments/environment.prod.ts
…voegen we onze Firebase configuratie toe:
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>' }};
U kunt de vereiste configuratiedetails voor de bovenstaande bestanden krijgen door te klikken op “Voeg Firebase toe aan uw web app” op de projectoverzichtspagina.
Daarna nemen we de Firebase modules op in onze app.module.ts
:
import { AngularFireModule } from 'angularfire2';import { AngularFireDatabaseModule } from 'angularfire2/database';import { environment } from '../environments/environment';// ...Imports:
En in add-memory.component.ts
injecteren we de database in de constructor en slaan we de waarden van het formulier op in de database. Als de push belofte van Firebase succesvol is, loggen we het succes in de console en resetten het model:
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') }) }
U moet publieke toegang toestaan op de databaseregels, zodat anonieme gebruikers kunnen lezen van en schrijven naar de database. Houd er rekening mee dat met deze instelling elke gebruiker in staat is om uw app-gegevens te lezen, wijzigen of verwijderen. Zorg ervoor dat u uw regels dienovereenkomstig instelt voordat u naar productie gaat.
Ook moet u het ng serve
-proces opnieuw starten om de omgevingswijzigingen op te pikken.
Nu, wanneer we teruggaan naar de browser en op onze opslaan-knop klikken, zullen we zien dat het geheugen is toegevoegd aan de database:
Laten we eens kijken hoe we onze herinneringen kunnen ophalen en weergeven in de materiaaltabel.
Terug hebben we de tabel gemaakt met ng generate @angular/material:material-table --name=view-memories', we automatically got a file
view-memories/view-memories-datasource.ts`. Dit bestand bevat nep-gegevens, dus we moeten het veranderen om te beginnen met het trekken uit Firebase.
In view-memories-datasource.ts
, zullen we de EXAMPLE_DATA
verwijderen en een lege array instellen:
export class ViewMemoriesDataSource extends DataSource<ViewMemoriesItem> { data: ViewMemoriesItem = ;// ...
En in getSortedData
zullen we de veldnamen bijwerken:
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; } });}
In view-memories.component.html
zullen we de namen van de kolommen bijwerken tot date
en text
van ons geheugenmodel. Merk op dat aangezien we de datum in milliseconden formaat hebben opgeslagen, we hier een date pipe gebruiken om de waarde te transformeren voor weergave in een meer mensvriendelijk datum formaat. Tenslotte verwijderen we de ="dataSource.data.length"
uit de paginator, omdat we de data asynchroon uit Firebase zullen laden:
<div class="mat-elevation-z8"> <table mat-table #table ="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 ="0" ="50" =""> </mat-paginator></div>
Verander de view-memories.component.css
in view-memories.component.scss
en stel de tabelstijl in:
table{ width: 100%;}
In view-memories.component.ts
, veranderen we de styleUrls
om de bovenstaande hernoeming naar ./view-memories.component.scss
weer te geven. We zullen ook de displayedColumns
array bijwerken tot en de tabel datasource instellen om gegevens van Firebase te krijgen.
Wat er hier gebeurt is dat we ons abonneren op de herinneringen lijst en wanneer we de gegevens ontvangen instantiëren we de ViewMemoriesDataSource
en stellen de data property in met de gegevens van 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 retourneert een ReactiveX-stijl Observable array.
Merk op dat we this.db.list<ViewMemoriesItem>('memories')
-de waarden die uit het 'memories'
-pad zijn gehaald, casten naar ViewMemoriesItem
. Dit wordt verzorgd door de angularfire2
bibliotheek.
We hebben ook de unsubscribe
oproep opgenomen in de onDestroy
haak van de Angular component lifecycle.
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: })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 = ; 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(); }}
Plaatsing naar Firebase Hosting
Nu, om onze app live te zetten, laten we hem deployen naar Firebase Hosting. Daarvoor installeren we de Firebase CLI, die het firebase
commando beschikbaar maakt:
npm install -g firebase-tools
Nu kunnen we Firebase CLI gebruiken om in te loggen:
firebase login
Dit zal u vragen om uw Google-account te selecteren.
Volgende, zullen we het project initialiseren en Firebase Hosting configureren:
firebase init
We zullen gewoon de Hosting optie selecteren.
Volgende, wanneer ons om het pad wordt gevraagd, zullen we het instellen op dist/my-memories
. Wanneer ons wordt gevraagd of we het willen configureren als een single-page app (d.w.z. alle URL’s herschrijven naar /index.html
), antwoorden we “ja.”
Ten slotte klikken we op, “File dist/my-memories/index.html already exists. Overschrijven?” Hier zeggen we “nee.”
Dit zal de Firebase config bestanden .firebaserc
en firebase.json
aanmaken met de gegeven configuratie.
De laatste stap is om te draaien:
ng build --prodfirebase deploy
En daarmee hebben we de app gepubliceerd naar de Firebase, die ons een URL geeft om naar te navigeren, zoals https://my-memories-b4c52.firebaseapp.com/view-memories, waar u mijn eigen gepubliceerde demo kunt bekijken.
Wauw, je hebt de tutorial doorstaan! Ik hoop dat je het leuk vond. Je kunt ook de volledige code bekijken op GitHub.
One Step at a Time
Angular is een zeer krachtig framework voor het bouwen van webapps. Het is er al een lange tijd en heeft zich bewezen voor kleine, eenvoudige apps en grote, complexe apps – Angular 6 is hier geen uitzondering.
Vooruitgang, Angular is van plan om te blijven verbeteren en nieuwe webparadigma’s te volgen, zoals webcomponenten (Angular Elements). Als u geïnteresseerd bent in het bouwen van hybride apps, kunt u kijken naar Ionic, dat Angular gebruikt als onderliggend framework.
Deze tutorial behandelde zeer basisstappen om te beginnen met het gebruik van Angular, Material, en Firebase. Maar je moet er rekening mee houden dat voor real-world toepassingen, moet je validatie toe te voegen, en om uw aanvraag gemakkelijker te onderhouden en schaalbaar te maken, zou je waarschijnlijk willen best practices te volgen, zoals het gebruik van diensten, herbruikbare componenten, enz. Dat zal het onderwerp van een ander artikel moeten zijn-hopelijk was dit genoeg om je eetlust voor Angular ontwikkeling op te wekken!
Leave a Reply