Angular 6 Tutorial: Új funkciók új erővel
Angular 6 megjelent! A legkiemelkedőbb változások a CLI-jét és a szolgáltatások injektálásának módját érintik. Ha a legelső Angular 6-os alkalmazásodat – vagy Angular/Firebase alkalmazást – szeretnéd megírni, ebben a bemutatóban átvesszük a kezdeti beállítások alapvető lépéseit, és létrehozunk egy kis naplóalkalmazást.
Angular 6: Az alapok
Ha még sosem használtad az Angular-t, hadd adjak egy rövid leírást róla és a működéséről.
Angular egy JavaScript-keretrendszer, amelyet az egyoldalas alkalmazások (SPA-k) építésének támogatására terveztek asztali és mobileszközökre egyaránt.
A keretrendszer irányelvek és modulok teljes készletét tartalmazza, amelyek segítségével könnyedén megvalósíthatja a webes alkalmazások leggyakoribb forgatókönyveit, például a navigációt, az engedélyezést, az űrlapokat és a jelentéstételt. Emellett tartalmazza az összes szükséges csomagot a Jasmine keretrendszerrel történő tesztek hozzáadásához és azok futtatásához a Karma vagy Protractor tesztfuttatókkal.
Angular architektúra a komponensekre, sablonokra, direktívákra és szolgáltatásokra épül. Beépített függőségi injektálási mechanizmust biztosít a szolgáltatások számára, valamint kétirányú adatkötést a nézetek és a komponenskód összekapcsolására.
Angular TypeScriptet használ, ami a JS egy tipizált szuperhalmaza, és megkönnyít néhány dolgot, különösen, ha tipizált nyelvi háttérrel rendelkezel.
Angular 6: Új funkciók
Az Angular 6 újdonságainak rövid összefoglalása:
- A keretrendszercsomagok (
@angular/core
,@angular/common
,@angular/compiler
stb.), a CLI, a Material és a CDK fő verziószámainak szinkronizálásának irányelve. Ez segíteni fogja a keresztkompatibilitás egyértelműbbé tételét a jövőben: A verziószámra vetett gyors pillantásból meg lehet állapítani, hogy a kulcscsomagok kompatibilisek-e egymással. - Új
ng
CLI-parancsok:-
ng update
a csomagverziók okos frissítéséhez, a függőségi verziók frissítéséhez és szinkronban tartásához. (Pl. ang update @angular/core
futtatásakor az összes keretrendszer és az RxJS is frissül.) A program lefuttatja a sémákat is, ha a csomag tartalmazza azokat. (Ha egy újabb verzió olyan törést okozó változásokat tartalmaz, amelyek kódmódosítást igényelnek, a séma frissíti helyetted a kódodat.) -
ng add
új csomagok hozzáadásához (és adott esetben szkriptek futtatásához)
-
- A szolgáltatások most már az őket biztosító modulokra hivatkoznak, nem pedig a modulok hivatkoznak a szolgáltatásokra, ahogy eddig volt.
Egy példa arra, hogy mit jelent ez utóbbi változás, ahol a kódod korábban így nézett ki:
@NgModule({ // ... providers: })
…ezzel a bizonyos változással az Angular 6-ban így fog kinézni:
@Injectabe({ providedIn: 'root',})
Ezeket nevezzük tree-shakeable providereknek, és lehetővé teszik a fordító számára, hogy eltávolítsa a nem hivatkozott szolgáltatásokat, ami kisebb méretű csomagokat eredményez.
Angular 6 CLI
A ng
parancssori felület egy nagyon fontos része az Angularnak, és lehetővé teszi, hogy gyorsabban haladj az alkalmazásod kódolása során.
A CLI segítségével nagyon könnyen felépítheted az alkalmazás kezdeti beállításait, új komponenseket, direktívákat stb. generálhatsz, és építheted és futtathatod az alkalmazásodat a helyi környezetedben.
Egy Angular 6 projekt létrehozása
Oké, elég a beszédből. Koszoljuk be a kezünket, és kezdjünk el kódolni.
Kezdéshez szükségünk lesz a Node.js és az npm telepítésére a gépünkön.
Most, menjünk előre és telepítsük a CLI-t:
npm install -g @angular/cli
Ez a ng
CLI parancsot fogja globálisan telepíteni, a -g
kapcsolónak köszönhetően.
Ha ez megvan, akkor a ng new
segítségével megkapjuk az alkalmazásunk kezdeti állványzatát:
ng new my-memories --style=scss
Ez létrehoz egy my-memories
mappát, létrehozza az összes szükséges fájlt, hogy a kezdeti beállítás készen álljon az indításra, és telepíti az összes szükséges csomagot. A --style=scss
kapcsoló opcionális, és beállítja a fordítót, hogy az SCSS fájlokat CSS-re fordítsa, amire később szükségünk lesz.
Amikor a telepítés befejeződött, akkor cd my-memories
és futtathatjuk a ng serve
. Ez elindítja a build folyamatot és egy helyi webkiszolgálót, amely kiszolgálja az alkalmazásunkat http://localhost:4200
.
A színfalak mögött az történik, hogy a CLI az összes .ts
(TypeScript fájlokat) átfordítja vanilla JS-be, összegyűjti az összes szükséges függőséget a packages mappából node_modules
, és az eredményt egy fájlkészletben adja ki, amelyet a 4200-as porton futó helyi webszerver szolgál ki.
Projekt fájlok
Ha nem ismered az Angular projekt mappaszerkezetét, a legfontosabb tudnivaló, hogy az alkalmazással kapcsolatos összes kód a src
mappába kerül. Általában az összes modult és direktívát ebben a mappában hozod létre az alkalmazás architektúráját követve (pl. felhasználó, kosár, termék.)
Eredeti beállítás
Oké, eddig megvan az alkalmazásunk kezdeti beállítása. Kezdjünk hozzá néhány változtatáshoz.
Mielőtt elkezdenénk, ássuk be magunkat egy kicsit a src
mappába. A kezdeti oldal 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>
Itt néhány alapvető HTML és a <app-root>
tag látható. Ez egy Angular komponens, és ahová az Angular 6 beilleszti a komponens kódunkat.
Megtaláljuk a app/app.component.ts
fájlt, amely a app-root
szelektorral rendelkezik, hogy megfeleljen annak, ami a index.html
fájlban van.
A komponens egy díszített TypeScript osztály, és ebben az esetben a title
tulajdonságot tartalmazza. A @Component
dekorátor azt mondja az Angularnak, hogy a komponens viselkedését foglalja bele az osztályba. A szelektoron kívül megadja, hogy melyik HTML fájlt renderelje és milyen stíluslapokat használjon.
import { Component } from '@angular/core';@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: })export class AppComponent { title = 'app';}
Ha megnézzük a app.component.html
-t, akkor láthatjuk a {{title}}
interpolációs kötést. Itt történik az összes mágikus kötés, és az Angular rendereli az osztály title tulajdonságának értékét, és frissíti azt minden alkalommal, amikor az megváltozik.
<!--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>
Lépjünk tovább, és frissítsük az title
-t az osztályból 'My Memories!'
-ra.
...export class AppComponent { title = 'My Memories!';}...
Láthatjuk, hogy a fordító feldolgozza a módosításunkat, és a böngésző frissül, hogy megjelenítse a frissített címünket.
Ez azt jelenti, hogy az Angular 6 ng serve
figyeli a fájlunk változásait, és minden alkalommal rendereli, amikor bármilyen fájlban változás történik.
A kódolás barátságosabbá tétele és a teljes oldalfrissítés elkerülése érdekében minden változtatás alkalmával kihasználhatjuk a webpack Hot Module Replacement (HMR) előnyeit, amely csak a JS/CSS megváltozott darabját frissíti ahelyett, hogy teljes frissítést produkálna a változtatásaink megjelenítéséhez.
A HMR konfigurálása
Először is be kell állítanunk a környezetet.
Készítsünk egy src/environments/environment.hmr.ts
fájlt a következő tartalommal:
export const environment = { production: false, hmr: true};
Frissítsük a src/environments/environment.prod.ts
fájlt, és adjuk hozzá a hmr: false
jelzőt a környezethez:
export const environment = { production: true, hmr: false};
Majd frissítsük a src/environments/environment.ts
fájlt, és ott is adjuk hozzá a hmr: false
jelzőt a környezethez:
export const environment = { production: false, hmr: false};
Majd a angular.json
fájlban frissítsük ezt a részt:
"projects": { "my-memories": { // ... "architect": { "build": { // ... "configurations": { "hmr":{ "fileReplacements": }, // ...
És a projects
alatt → my-memories
→ architect
→ serve
→ configurations
:
"projects": { "my-memories": { "architect": { // ... "serve": { // ... "configurations": { "hmr": { "browserTarget": "my-memories:build:hmr" }, // ...
Most frissítsük a tsconfig.app.json
-t, hogy tartalmazza a szükséges types
(nos, típusát) a compilerOptions
alatt:
"compilerOptions": { // ... "types":
A következőkben telepítjük a @angularclass/hmr
modult, mint fejlesztési függőséget:
npm install --save-dev @angularclass/hmr
Aztán konfiguráljuk egy src/hmr.ts
fájl létrehozásával:
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(); });};
Következő lépésként frissítsük a src/main.ts
modult, hogy a fenti függvényt használja:
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));}
Azt csináljuk itt, hogy a bootstrap meghív egy anonim függvényt, és ezután megkérdezzük, hogy a environment.hmr
flag igaz-e. Ez a következő lépés. Ha igen, akkor meghívjuk a korábban definiált függvényt a hmr.ts
-ből, amely lehetővé tette a forró modulcserét; ellenkező esetben a bootstrap-et a korábbiak szerint használjuk.
Most, amikor a ng serve --hmr --configuration=hmr
-t futtatjuk, akkor a hmr
konfigurációt hívjuk meg, és amikor változtatunk a fájlokon, akkor teljes frissítés nélkül kapunk frissítéseket. Az első --hmr
a webpack számára, a --configuration=hmr
pedig az Angular számára, hogy használja a hmr
környezetet.
Progresszív webes alkalmazás (PWA)
Az Angular 6 PWA támogatás hozzáadásához és az alkalmazás offline betöltésének engedélyezéséhez használhatjuk az egyik új CLI parancsot, ng add
:
ng add @angular/
Megjegyzem, hogy a verziót hozzáadom, mivel a legújabb verzió, amikor ezt a bemutatót írtam, hibát dobott. (Kipróbálhatod nélküle is, és ellenőrizheted, hogy működik-e nálad egyszerűen a ng add @angular/pwa
használatával.)
Oké, tehát miután lefuttattuk a parancsot, sok változást fogunk látni a projektünkön. A legfontosabb változások, hogy hozzáadta:
- Hivatkozás a
manifest.json
-re aangular.json
assets fájlban, hogy az szerepeljen a build outputban, valamint"serviceWorker": true
a production buildekben - A
ngsw-config.json
fájl a kezdeti beállításokkal, hogy az alkalmazás futtatásához szükséges összes fájlt gyorsítótárba helyezze - A
manifest.json
meta tag aindex.html
fájlban - A
manifest.json
fájl maga, az alkalmazás alapkonfigurációjával - A szolgáltatási munkás betöltése az alkalmazás modulban
ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production })
(megjegyzendő, hogy a szolgáltatási munkás csak termelési környezetben lesz engedélyezve)
Ez most azt jelenti, hogy amikor a felhasználó először lép be az URL-re, a fájlok letöltődnek. Ezután, ha a felhasználó megpróbálja elérni az URL-t hálózati szolgáltatás nélkül, akkor az alkalmazás továbbra is működni fog azáltal, hogy lehúzza ezeket a gyorsítótárazott fájlokat.
A Material Angular 6 UI könyvtár hozzáadása
Ezidáig megvan a kezdeti beállítás, és készen állunk az alkalmazásunk építésének megkezdésére. A már megépített komponensek felhasználásához használhatjuk a Material Angular 6-os verzióját.
Az material
csomag telepítéséhez az alkalmazásunkra ismét a ng add
:
ng add @angular/material
Futtatás után látni fogjuk, hogy néhány új csomagot adtunk hozzá és néhány alapvető stíluskonfigurációt:
-
index.html
tartalmazza a Roboto betűtípust és a Material ikonok -
BrowserAnimationsModule
hozzáadódik aAppModule
-
angular.json
az indigó-pink témát már tartalmazza számunkra
Újra kell indítanunk ng serve
, hogy felvegyük a témát, Vagy választhat egy másik előre elkészített témát.
Basic Layout
A kezdeti sidenav elrendezéshez a Materialhoz mellékelt sémákat fogjuk használni. De nem baj, ha más elrendezést szeretne használni.
(Dióhéjban, a sémák segítségével transzformációkat alkalmazhat a projektre: Szükség szerint létrehozhat, módosíthat vagy törölhet fájlokat. Ebben az esetben egy sidenav elrendezést készít az alkalmazásunkhoz.)
ng generate @angular/material:material-nav --name=my-nav
Ezzel létrehoz egy sidenav komponenst a minimális beállításokkal, készen az indításra. Hát nem nagyszerű?
Az összes szükséges modult is tartalmazta a app.module.ts
-ben.
Mivel SCSS-t használunk, át kell neveznünk a my-nav.component.css
fájlt my-nav.component.scss
-re, és a my-nav.component.ts
-ben frissíteni kell a megfelelő styleUrls
hivatkozást az új név használatára.
Az új komponens használatához most menjünk a app.component.html
-be, és távolítsuk el az összes kezdeti kódot, így csak:
<app-my-nav></app-my-nav>
Ha visszamegyünk a böngészőbe, a következőt fogjuk látni:
Frissítsük a linkeket, hogy csak a kívánt két lehetőség legyen.
Először is hozzunk létre két új komponenst:
ng g c AddMemoryng generate @angular/material:material-table --name=view-memories
(A második egy anyagséma, amelyet egy táblázat létrehozására használunk.)
Következő lépésként a my-nav
-ben frissítsük a linkek beállításához és a <router-outlet>
beépítéséhez a <router-outlet>
-t a tartalmi összetevőink megjelenítéséhez:
<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>
Az app.component.html
-ben is frissítenünk kell, hogy csak a fő <router-outlet>
(ill, távolítsuk el a <my-nav>
-t):
<router-outlet></router-outlet>
Következő lépésként a AppModule
-ban beillesztjük az útvonalakat:
import { RouterModule, Routes } from '@angular/router';// ...imports: }, ]),]
Megjegyezzük, hogy a MyNavComponent
-t állítjuk be szülőnek és a két általunk létrehozott komponenst gyermeknek. Ez azért van így, mert a <router-outlet>
-t felvettük a MyNavComponent
-ba, és amikor a két útvonal valamelyikét elérjük, a gyermekkomponenst fogjuk megjeleníteni, ahová a <router-outlet>
került.
Az alkalmazás kiszolgálásakor ezt követően azt kell látnunk:
Az alkalmazás elkészítése (Az emlékek naplója)
Oké, most hozzuk létre az űrlapot, amellyel új emlékeket menthetünk a naplónkba.
Importálnunk kell néhány anyagmodult és az űrlapok modult a app.module.ts
-ünkbe:
import { FormsModule } from '@angular/forms';import { MatCardModule, MatFormFieldModule, MatInputModule, MatDatepickerModule, MatNativeDateModule } from '@angular/material';// ...Imports:
Az add-memory.component.html
-ben pedig hozzáadjuk az űrlapot:
<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>
Itt egy mat-card
-et használunk, és két mezőt adunk hozzá, egy date
-et és egy textarea
-et.
Megjegyezzük, hogy a -et használjuk. Ez az Angular direktíva fogja egymáshoz kötni a
memory.date
kifejezést és az osztályban lévő memory
tulajdonságot, ahogy azt később látni fogjuk. (A szintaktikai cukor – egy rövidítés arra, hogy kétirányú adatkötést hajtsunk végre az osztályból a nézethez és a nézetből az osztályhoz. Ez azt jelenti, hogy amikor szöveget írunk be a nézetben, a
memory.date
tükrözi ezeket a változásokat az osztálypéldányban, és ha az osztálypéldányban módosítjuk a memory.date
-t, a nézet is tükrözi a változásokat.)
A add-memory.component.ts
-ben a kód így fog kinézni:
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); }}
Itt a ngModel
segítségével kötött memory
tulajdonságot inicializáljuk. Amikor a AddMemoryComponent
komponens példányosításra kerül, a memory
egy üres objektum lesz. Ezután, amikor a ngModel
direktíva fut, képes lesz hozzárendelni a bemeneti értéket a memory.date
és memory.text
tulajdonságokhoz. Ha ezt nem tennénk meg, akkor Cannot set property 'date/text' of undefined
hibát kapnánk.
Mindeközben a add-memory.component.scss
-nek rendelkeznie kell:
.memory-card { min-width: 150px; max-width: 400px; width: 100%; margin: auto;}.mat-form-field { width: 100%;}
Mióta megvan a <pre> {{ memory | json }} </pre>
, láthatjuk a memory
aktuális állapotát a nézetben. Ha a böngészőbe lépünk, itt az eddigi eredmény:
A nézetben az űrlapot a (ngSubmit)="onSubmit()"
-en keresztül az osztályban lévő onSubmit
függvényhez kötöttük.
onSubmit() { console.log(this.memory); }
A “Ments meg!” gombra kattintva tehát a konzolnaplóba küldött felhasználói bemenet belső reprezentációját kapjuk:
Angular 6 Tutorial: Csatlakozás a Firebase-hez
A következő lépés az lesz, hogy a projektünket csatlakoztatjuk a Firebase-hez, hogy elmenthessük az emlékeinket.
Először is menjünk a Firebase konzolra, és hozzunk létre ott egy projektet.
Második lépésként telepítjük a firebase
és angularfire2
csomagokat:
npm install firebase angularfire2 --save
Majd mindhárom fájlba:
/src/environments/environment.ts
/src/environments/environment.hmr.ts
/src/environments/environment.prod.ts
…hozzáadjuk a Firebase configunkat:
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>' }};
A fenti fájlok szükséges konfigurációs adatait a projekt áttekintő oldalán a “Firebase hozzáadása a webalkalmazáshoz” gombra kattintva kaphatjuk meg.
Ezután a Firebase modulokat beillesztjük a app.module.ts
-ünkbe:
import { AngularFireModule } from 'angularfire2';import { AngularFireDatabaseModule } from 'angularfire2/database';import { environment } from '../environments/environment';// ...Imports:
A add-memory.component.ts
-ben pedig a konstruktorba injektáljuk az adatbázist, és az űrlap értékeinek az adatbázisba történő mentését. Ha a Firebase-től érkező push promise sikeres, akkor a konzolban naplózzuk a sikert, és visszaállítjuk a modellt:
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') }) }
Az adatbázis szabályainál engedélyeznie kell a nyilvános hozzáférést, így a névtelen felhasználók olvashatnak és írhatnak róla. Vegye figyelembe, hogy ezzel a beállítással bármelyik felhasználó képes lesz olvasni/megváltoztatni/törölni az alkalmazás adatait. Győződjön meg róla, hogy a szabályokat ennek megfelelően állította be, mielőtt a termelésbe lép.
Azért, hogy felvegye a környezeti változásokat, újra kell indítania a ng serve
folyamatot.
Most, amikor visszamegyünk a böngészőbe és rákattintunk a mentés gombra, látni fogjuk, hogy a memória hozzá lett adva az adatbázishoz:
Nézzük meg, hogyan tudjuk lekérni az emlékeinket és megjeleníteni őket az Anyag táblázatban.
Még korábban létrehoztuk a táblázatot a ng generate @angular/material:material-table --name=view-memories', we automatically got a file
view-memories/view-memories-datasource.ts` segítségével. Ez a fájl hamis adatokat tartalmaz, ezért meg kell változtatnunk, hogy a Firebase-ből kezdjük el húzni.
A view-memories-datasource.ts
-ben eltávolítjuk a EXAMPLE_DATA
-et, és egy üres tömböt állítunk be:
export class ViewMemoriesDataSource extends DataSource<ViewMemoriesItem> { data: ViewMemoriesItem = ;// ...
És a getSortedData
-ben frissítjük a mezők nevét:
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; } });}
A view-memories.component.html
-ben frissítjük az oszlopok nevét date
-re és text
-ra a memória modellünkből. Vegyük észre, hogy mivel a dátumot milliszekundum formátumban mentettük el, itt egy date pipe segítségével alakítjuk át az értéket a megjelenítéshez egy emberbarátabb dátumformátumba. Végül eltávolítjuk a ="dataSource.data.length"
-et a paginátorból, mivel az adatokat aszinkron módon fogjuk betölteni a Firebase-ből:
<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>
A view-memories.component.css
-et view-memories.component.scss
-re változtatjuk, és beállítjuk a táblázat stílusát:
table{ width: 100%;}
A view-memories.component.ts
-ben a styleUrls
-et a fenti átnevezésnek megfelelően ./view-memories.component.scss
-re módosítjuk. A displayedColumns
tömböt is frissítjük -re, és beállítjuk a táblázat adatforrását, hogy adatokat kapjon a Firebase-ből.
Az történik itt, hogy feliratkozunk az emlékek listájára, és amikor megkapjuk az adatokat, akkor instanciáljuk a ViewMemoriesDataSource
-t, és beállítjuk az adat tulajdonságát a Firebase-ből származó adatokkal.
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;});
A Firebase egy ReactiveX stílusú Observable tömböt ad vissza.
Megjegyezzük, hogy a this.db.list<ViewMemoriesItem>('memories')
-at 'memories'
útvonalból húzott értékeket a ViewMemoriesItem
-be vetítjük. Erről a angularfire2
könyvtár gondoskodik.
Az unsubscribe
hívást az Angular komponens életciklusának onDestroy
kampóján belül is beépítettük.
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(); }}
Deploying to Firebase Hosting
Most, hogy az alkalmazásunk éles legyen, telepítsük a Firebase Hostingra. Ehhez telepítsük a Firebase CLI-t, ami elérhetővé teszi a firebase
parancsot:
npm install -g firebase-tools
Most már használhatjuk a Firebase CLI-t a bejelentkezéshez:
firebase login
Ez a Google fiók kiválasztását kéri.
A következő lépésben inicializáljuk a projektet és konfiguráljuk a Firebase Hostingot:
firebase init
Egyszerűen csak a Hosting opciót választjuk ki.
A következő lépésben, amikor az elérési utat kéri, akkor a dist/my-memories
értéket állítjuk be. Amikor megkérdezik, hogy egyoldalas alkalmazásként konfiguráljuk-e (azaz minden URL-t átírunk-e /index.html
-re), igennel válaszolunk.”
Végül leütjük: “A dist/my-memories/index.html fájl már létezik. Overwrite?” Itt azt válaszoljuk, hogy “nem.”
Ez létrehozza a Firebase .firebaserc
és firebase.json
konfigurációs fájlokat a megadott konfigurációval.
Az utolsó lépés a futtatás:
ng build --prodfirebase deploy
És ezzel már publikáltuk is az alkalmazást a Firebase-re, ami egy URL-t biztosít számunkra, ahová navigálhatunk, mint például https://my-memories-b4c52.firebaseapp.com/view-memories, ahol megtekinthetjük a saját publikált demómat.
Hű, végigmentél a tutorialon! Remélem, élvezted. A teljes kódot is megnézheted a GitHubon.
One Step at a Time
Angular egy nagyon hatékony keretrendszer webes alkalmazások építéséhez. Már régóta létezik, és bizonyított kis, egyszerű és nagy, összetett alkalmazásokhoz egyaránt – az Angular 6 sem kivétel ez alól.
Az Angular a jövőben is tervezi a folyamatos fejlesztést és az új webes paradigmák követését, mint például a webkomponensek (Angular Elements). Ha hibrid alkalmazások építése érdekli, megnézheti az Ionicot, amely az Angular-t használja alapul szolgáló keretrendszerként.
Ez a bemutató nagyon alapvető lépéseket fedett le az Angular, a Material és a Firebase használatának megkezdéséhez. De figyelembe kell vennie, hogy a valós alkalmazásokhoz validációt kell hozzáadni, és hogy az alkalmazás könnyebben karbantartható és skálázható legyen, valószínűleg a legjobb gyakorlatokat szeretné követni, mint például a szolgáltatások, újrafelhasználható komponensek stb. használata. Ez egy másik cikk témája lesz – remélhetőleg ez a cikk elég volt ahhoz, hogy kedvet csináljon az Angular fejlesztéshez!
Leave a Reply