Cara Membuat Dan Menyebarkan Aplikasi Material Sudut
Diterbitkan: 2022-03-10Angular adalah salah satu pilihan populer saat membuat aplikasi web baru. Selain itu, spesifikasi "Desain Material" telah menjadi pilihan utama untuk menciptakan pengalaman minimal dan menarik saat ini. Jadi, setiap proyek "Angular" baru sebagian besar menggunakan "Perpustakaan Desain Material Sudut" untuk menggunakan komponen yang mengikuti spesifikasi desain material. Dari animasi yang halus hingga umpan balik interaksi yang tepat, semua ini sudah tersedia sebagai bagian dari perpustakaan desain material resmi untuk angular.
Setelah aplikasi web dikembangkan, langkah selanjutnya adalah men-deploy-nya. Di situlah "Netlify" muncul. Dengan antarmuka yang sangat mudah digunakan, penerapan otomatis, pemisahan lalu lintas untuk pengujian A/B dan berbagai fitur lainnya, Netlify jelas merupakan alat yang hebat.
Artikel ini akan menjadi panduan membuat aplikasi web Angular 8 menggunakan perpustakaan resmi Desain Material Angular. Kami akan membuat aplikasi web pembuat Kode QR sepenuhnya berdasarkan Angular saat dihosting di Netlify.
File untuk tutorial ini dapat ditemukan di GitHub dan versi demo digunakan di sini.
Mulai
- Instal Sudut 8,
- Buat akun GitHub,
- Instal Git di komputer Anda,
- Buat akun Netlify.
Catatan : Saya akan menggunakan VSCode dan Microsoft Windows sebagai IDE dan OS pilihan, meskipun langkah-langkahnya akan serupa untuk IDE lain di OS lain.
Setelah prasyarat di atas selesai, mari kita mulai!
Mock & Perencanaan
Sebelum kita mulai membuat proyek, akan bermanfaat untuk merencanakan ke depan: UI seperti apa yang kita inginkan dalam aplikasi kita? Apakah akan ada potongan yang dapat digunakan kembali? Bagaimana aplikasi akan berinteraksi dengan layanan eksternal?
Pertama, periksa tiruan UI.
Ini adalah tiga halaman berbeda yang akan dimuat dalam aplikasi. Beranda akan menjadi titik awal aplikasi kita. Membuat halaman QR harus berurusan dengan pembuatan kode QR baru. Halaman Riwayat akan menampilkan semua kode QR yang disimpan.
Maket tidak hanya memberikan gambaran tentang tampilan dan nuansa aplikasi, tetapi juga memisahkan tanggung jawab setiap halaman.
Satu pengamatan (dari ejekan) adalah tampaknya bilah navigasi atas umum di semua halaman. Dengan demikian, bilah navigasi dapat dibuat sebagai komponen yang dapat digunakan kembali dan digunakan kembali.
Sekarang kita memiliki sedikit ide tentang bagaimana aplikasi akan terlihat dan apa yang dapat digunakan kembali, mari kita mulai.
Membuat Proyek Sudut Baru
Luncurkan VSCode, lalu buka jendela terminal di VSCode untuk menghasilkan proyek Angular baru.
Terminal akan terbuka dengan jalur default seperti yang ditunjukkan pada prompt. Anda dapat mengubah ke direktori pilihan sebelum melanjutkan; dalam kasus Windows, saya akan menggunakan perintah cd
.
Ke depan, angular-cli memiliki perintah untuk menghasilkan proyek ng new <project-name>
. Cukup gunakan nama proyek mewah yang Anda suka dan tekan enter, misalnya ng new qr
.
Ini akan memicu sihir angular-cli; itu akan memberikan beberapa opsi untuk mengonfigurasi beberapa aspek proyek, misalnya, menambahkan perutean sudut. Kemudian, berdasarkan opsi yang dipilih, itu akan menghasilkan seluruh kerangka proyek yang dapat dijalankan tanpa modifikasi apa pun.
Untuk tutorial ini, masukkan Yes untuk perutean dan pilih CSS untuk penataan. Ini akan menghasilkan proyek Angular baru:
Kami sekarang telah mendapatkan proyek Angular yang berfungsi penuh. Untuk memastikan semuanya berfungsi dengan baik, kita dapat menjalankan proyek dengan memasukkan perintah ini di terminal: ng serve
. Uh oh, tapi tunggu, ini menghasilkan kesalahan. Apa yang bisa terjadi?
Jangan khawatir. Setiap kali Anda membuat proyek baru menggunakan angular-cli, itu menghasilkan seluruh kerangka di dalam folder yang dinamai menurut nama proyek yang ditentukan dalam perintah ng new qr
. Di sini, kita harus mengubah direktori kerja saat ini menjadi yang baru saja dibuat. Di Windows, gunakan perintah cd qr
untuk mengubah direktori.
Sekarang, coba jalankan proyek lagi dengan bantuan ng serve
:
Buka browser web, buka URL https://localhost:4200 untuk melihat proyek berjalan. Perintah ng serve
menjalankan aplikasi pada port 4200 secara default.
TIPS : Untuk menjalankannya di port yang berbeda, kita menggunakan perintah ng serve --port <any-port>
misalnya, ng serve --port 3000
.
Ini memastikan bahwa proyek Angular dasar kami aktif dan berjalan. Mari kita lanjutkan.
Kita perlu menambahkan folder proyek ke VSCode. Buka menu "File" dan pilih "Buka Folder" dan pilih folder proyek. Folder proyek sekarang akan ditampilkan dalam tampilan Explorer di sebelah kiri.
Menambahkan Pustaka Bahan Sudut
Untuk menginstal pustaka material Angular, gunakan perintah berikut di jendela terminal: ng add @angular/material
. Ini akan (sekali lagi) mengajukan beberapa pertanyaan seperti tema apa yang Anda inginkan, apakah Anda ingin animasi default, apakah dukungan sentuh diperlukan, antara lain. Kami hanya akan memilih tema Indigo/Pink
default, Yes
untuk menambahkan perpustakaan HammerJS
dan animasi browser.
Perintah di atas juga mengonfigurasi seluruh proyek untuk mengaktifkan dukungan untuk komponen material.
- Ia menambahkan dependensi proyek ke package.json ,
- Itu menambahkan font Roboto ke file index.html ,
- Itu menambahkan font ikon Desain Material ke index.html Anda,
- Itu juga menambahkan beberapa gaya CSS global ke:
- Hapus margin dari tubuh,
- Atur
height: 100%
ke dalam HTML dan badan, - Atur Roboto sebagai font aplikasi default.
Hanya untuk memastikan bahwa semuanya baik-baik saja, Anda dapat menjalankan proyek lagi pada saat ini, meskipun Anda tidak akan melihat sesuatu yang baru.
Menambahkan Halaman Beranda
Kerangka proyek kami sekarang siap. Mari kita mulai dengan menambahkan beranda.
Kami ingin membuat beranda kami tetap sederhana, seperti gambar di atas. Halaman beranda ini menggunakan beberapa komponen material bersudut. Mari kita membedah.
- Bilah atas adalah elemen
nav
HTML sederhana yang berisi tombol gaya material,mat-button
, dengan gambar dan teks sebagai turunannya. Warna bilah sama dengan warna primer yang dipilih saat menambahkan pustaka material Angular; - Gambar terpusat;
- Lain,
mat-button
, hanya dengan teks sebagai anaknya. Tombol ini akan memungkinkan pengguna untuk menavigasi ke halaman riwayat; - Lencana hitungan,
matBadge
, yang dilampirkan pada tombol di atas, menunjukkan jumlah kode QR yang disimpan oleh pengguna; - Tombol aksi mengambang,
mat-fab
, di sudut kanan bawah memiliki warna aksen dari tema yang dipilih.
Sedikit menyimpang, mari tambahkan komponen dan layanan lain yang diperlukan terlebih dahulu.
Menambahkan Header
Seperti yang direncanakan sebelumnya, bilah navigasi harus digunakan kembali, mari kita buat sebagai komponen sudut terpisah. Buka terminal di VSCode dan ketik ng gc header
(kependekan dari ng generate component header) dan tekan Enter. Ini akan membuat folder baru bernama "header" yang akan berisi empat file:
- header.component.css : digunakan untuk memberikan gaya untuk komponen ini;
- header.component.html : untuk menambahkan elemen HTML;
- header.component.spec.ts : untuk menulis kasus uji;
- header.component.ts : untuk menambahkan logika berbasis TypeScript.
Untuk membuat header terlihat seperti di tiruan, tambahkan HTML di bawah ini di header.component.html :
<nav class="navbar" [class.mat-elevation-z8]=true> <div> <button *ngIf="showBackButton" aria-hidden=false mat-icon-button routerLink="/"> <mat-icon> <i class="material-icons md-32">arrow_back</i> </mat-icon> </button> <span>{{currentTitle}}</span> </div> <button *ngIf="!showBackButton" aria-hidden=false mat-button class="button"> <img src="../../assets/qr-icon-white.png"> <span>QR Generator</span> </button> <button *ngIf="showHistoryNav" aria-hidden=false mat-button class="button" routerLink="/history"> <span>History</span> </button> </nav>
TIPS : Untuk menambahkan elevasi untuk setiap komponen material gunakan [class.mat-elevation-z8]=true
, nilai elevasi dapat diubah dengan mengubah nilai z , dalam hal ini adalah z8
. Misalnya, untuk mengubah elevasi menjadi 16, gunakan [class.mat-elevation-z16]=true
.
Dalam cuplikan HTML di atas, ada dua elemen material Angular yang digunakan: mat-icon
dan mat-button/mat-icon-button
. Penggunaannya sangat sederhana; pertama, kita perlu menambahkan keduanya sebagai modul di app.module.ts kita seperti yang ditunjukkan di bawah ini:
Ini akan memungkinkan kita untuk menggunakan dua elemen material Angular ini di mana saja dalam komponen apa pun.
Untuk menambahkan tombol material, cuplikan HTML berikut digunakan:
<button mat-button> Material Button </button>
Ada berbagai jenis elemen tombol material yang tersedia di perpustakaan material Angular seperti mat-raised-button
, mat-flat-button
, mat-fab
dan lainnya; ganti saja mat-button
di cuplikan kode di atas dengan tipe lainnya.
Elemen lainnya adalah mat-icon
yang digunakan untuk menampilkan ikon yang tersedia di pustaka ikon materi. Ketika pustaka material Angular ditambahkan di awal, maka referensi ke pustaka ikon material juga ditambahkan, yang memungkinkan kita menggunakan ikon dari beragam ikon.
Penggunaannya sesederhana:
<mat-icon> <i class="material-icons md-32">arrow_back</i> </mat-icon>
Tag <i>
bersarang dapat digunakan untuk mengubah ukuran ikon (ini dia md-32
) yang akan membuat ikon berukuran tinggi dan lebar 32px. Nilai ini bisa md-24
, md-48
, dan seterusnya. Nilai tag <i>
bersarang adalah nama ikon. (Nama dapat ditemukan di sini untuk ikon lainnya.)
Aksesibilitas
Setiap kali ikon atau gambar digunakan, sangat penting untuk menyediakan informasi yang memadai untuk tujuan aksesibilitas atau untuk pengguna pembaca layar. ARIA (Accessible Rich Internet Applications) mendefinisikan cara untuk membuat konten web dan aplikasi web lebih mudah diakses oleh penyandang disabilitas.
Satu hal yang perlu diperhatikan adalah bahwa elemen HTML yang memiliki semantik asli (misalnya nav
) tidak memerlukan atribut ARIA; pembaca layar sudah tahu bahwa nav
adalah elemen navigasi dan membacanya seperti itu.
Spesifikasi ARIA dibagi menjadi tiga kategori: peran, status, dan properti. Katakanlah div
digunakan untuk membuat bilah kemajuan dalam kode HTML. Itu tidak memiliki semantik asli; Peran ARIA dapat menggambarkan widget ini sebagai bilah kemajuan, properti ARIA dapat menunjukkan karakteristiknya seperti dapat diseret. Status ARIA akan menggambarkan statusnya saat ini seperti nilai bilah kemajuan saat ini. Lihat cuplikannya di bawah ini:
<div role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"> </div>
Demikian pula, atribut aria yang sangat umum digunakan: aria-hidden=true/false
digunakan. Nilai true membuat elemen tersebut tidak terlihat oleh pembaca layar.
Karena sebagian besar elemen UI yang digunakan dalam aplikasi ini memiliki makna semantik asli, satu-satunya atribut ARIA yang digunakan adalah untuk menentukan status visibilitas ARIA. Untuk informasi mendetail, lihat ini.
Header.component.html memang berisi beberapa logika untuk menyembunyikan dan menampilkan tombol kembali tergantung pada halaman saat ini. Selain itu, tombol Home juga berisi gambar/logo yang harus ditambahkan ke folder /assets
. Unduh gambar dari sini dan simpan di folder /assets
.
Untuk penataan bilah navigasi, tambahkan css di bawah ini di header.component.css :
.navbar { position: fixed; top: 0; left: 0; right: 0; z-index: 2; background: #3f51b5; display: flex; flex-wrap: wrap; align-items: center; padding: 12px 16px; } .button { color: white; margin: 0px 10px; }
Karena kami ingin agar komponen header dapat digunakan kembali di seluruh komponen lain, maka untuk memutuskan apa yang harus ditampilkan, kami akan memerlukannya sebagai parameter dari komponen lain. Ini membutuhkan penggunaan dekorator @Input()
yang akan mengikat variabel yang kita gunakan di header.component.html .
Tambahkan baris ini di file header.component.ts :
// Add these three lines above the constructor entry. @Input() showBackButton: boolean; @Input() currentTitle: string; @Input() showHistoryNav: boolean; constructor() { }
Ketiga binding di atas akan dilewatkan sebagai parameter dari komponen lain yang akan digunakan oleh komponen header. Penggunaannya akan lebih jelas setelah kita bergerak maju.
Selanjutnya, kita perlu membuat beranda yang dapat diwakili oleh komponen Angular. Jadi mari kita mulai dengan membuat komponen lain; ketik ng gc home
di terminal untuk membuat komponen home secara otomatis. Seperti sebelumnya, folder baru bernama "home" akan dibuat berisi empat file berbeda. Sebelum melanjutkan untuk memodifikasi file-file itu, mari tambahkan beberapa informasi perutean ke modul perutean sudut.
Menambahkan Perutean
Angular menyediakan cara untuk memetakan URL ke komponen tertentu. Setiap kali beberapa navigasi terjadi, kerangka kerja Angular memonitor URL dan berdasarkan informasi yang ada di file app-routing.module.ts ; itu menginisialisasi komponen yang dipetakan. Dengan cara ini komponen yang berbeda tidak perlu memikul tanggung jawab untuk menginisialisasi komponen lain. Dalam kasus kami, aplikasi memiliki tiga halaman yang dapat dinavigasi dengan mengklik tombol yang berbeda. Kami mencapai ini dengan memanfaatkan dukungan perutean yang disediakan oleh kerangka kerja Angular.
Komponen rumah harus menjadi titik awal aplikasi. Mari tambahkan informasi ini ke file app-routing.module.ts .
Properti path
disetel sebagai string kosong; ini memungkinkan kami untuk memetakan URL aplikasi ke komponen beranda, sesuatu seperti google.com
yang menunjukkan beranda Google.
TIP : Nilai jalur tidak pernah dimulai dengan “ /
”, melainkan menggunakan string kosong meskipun jalurnya bisa seperti search/coffee
.
Kembali ke komponen beranda, ganti konten home.component.html dengan ini:
<app-header [showBackButton]="false" [currentTitle]=""></app-header> <app-profile></app-profile> <!-- FAB Fixed --> <button mat-fab class="fab-bottom-right" routerLink="/create"> <mat-icon> <i class="material-icons md-48">add</i> </mat-icon> </button>
Ada tiga bagian komponen rumah:
- Komponen header yang dapat digunakan kembali
<app-header>
, - Komponen
<app-profile>
, - Tombol aksi mengambang di kanan bawah.
Cuplikan HTML di atas menunjukkan bagaimana komponen header yang dapat digunakan kembali digunakan di komponen lain; kami hanya menggunakan pemilih komponen dan memasukkan parameter yang diperlukan.
Komponen profil dibuat untuk digunakan sebagai isi beranda — kami akan segera membuatnya.
Tombol aksi mengambang dengan ikon +
adalah semacam tombol material sudut bertipe mat-fab
di kanan bawah layar. Ini memiliki arahan atribut routerLink
yang menggunakan informasi rute yang disediakan di app-routing.module.ts
untuk navigasi. Dalam hal ini, tombol memiliki nilai rute sebagai /create yang akan dipetakan untuk membuat komponen.
Untuk membuat tombol buat melayang di kanan bawah, tambahkan kode CSS di bawah ini di home.component.css :
.fab-bottom-right { position: fixed; left: auto; bottom: 5%; right: 10%; }
Karena komponen profil seharusnya mengelola isi halaman beranda, kami akan membiarkan home.component.ts
tetap utuh.
Menambahkan Komponen Profil
Buka terminal, ketik ng gc profile
dan tekan enter untuk menghasilkan komponen profil. Seperti yang direncanakan sebelumnya, komponen ini akan menangani bagian utama halaman beranda. Buka profile.component.html
dan ganti kontennya dengan ini:
<div class="center profile-child"> <img class="avatar" src="../../assets/avatar.png"> <div class="profile-actions"> <button mat-raised-button matBadge="{{historyCount}}" matBadgeOverlap="true" matBadgeSize="medium" matBadgeColor="accent" color="primary" routerLink="/history"> <span>History</span> </button> </div> </div>
Cuplikan HTML di atas menunjukkan cara menggunakan elemen matBadge
dari pustaka materi. Untuk dapat menggunakannya di sini, kita perlu mengikuti latihan biasa menambahkan MatBadgeModule
ke file app.module.ts
. Lencana adalah deskripsi status bergambar kecil untuk elemen UI seperti tombol atau ikon atau teks. Dalam hal ini, digunakan dengan tombol untuk menunjukkan jumlah QR yang disimpan oleh pengguna. Lencana perpustakaan bahan sudut memiliki berbagai properti lain seperti mengatur posisi lencana dengan matBadgePosition
, matBadgeSize
untuk menentukan ukuran, dan matBadgeColor
untuk mengatur warna lencana.
Satu lagi aset gambar perlu ditambahkan ke folder aset: Unduh. Simpan yang sama ke folder /assets
proyek.
Buka profile.component.css dan tambahkan ini:
.center { top: 50%; left: 50%; position: absolute; transform: translate(-50%, -50%); } .profile-child { display: flex; flex-direction: column; align-items: center; } .profile-actions { padding-top: 20px; } .avatar { border-radius: 50%; width: 180px; height: 180px; }
CSS di atas akan mencapai UI seperti yang direncanakan.
Selanjutnya, kita memerlukan semacam logika untuk memperbarui nilai hitungan histori seperti yang akan tercermin dalam matBadge
yang digunakan sebelumnya. Buka profile.component.ts dan tambahkan cuplikan berikut dengan tepat:
export class ProfileComponent implements OnInit { historyCount = 0; constructor(private storageUtilService: StorageutilService) { } ngOnInit() { this.updateHistoryCount(); } updateHistoryCount() { this.historyCount = this.storageUtilService.getHistoryCount(); } }
Kami telah menambahkan StorageutilService tetapi kami belum membuat layanan seperti itu sampai sekarang. Mengabaikan kesalahan, kami telah menyelesaikan komponen profil kami yang juga menyelesaikan komponen beranda kami. Kami akan mengunjungi kembali komponen profil ini setelah membuat layanan utilitas penyimpanan kami. Oke, kalau begitu mari kita lakukan.
Penyimpanan lokal
HTML5 menyediakan fitur penyimpanan web yang dapat digunakan untuk menyimpan data secara lokal. Ini memberikan lebih banyak penyimpanan dibandingkan dengan cookie — setidaknya 5MB vs 4KB. Ada dua jenis penyimpanan web dengan cakupan dan masa pakai yang berbeda: Lokal dan Sesi . Yang pertama dapat menyimpan data secara permanen sedangkan yang kedua bersifat sementara dan untuk satu sesi. Keputusan untuk memilih jenis dapat didasarkan pada kasus penggunaan, dalam skenario kami, kami ingin menyimpan di seluruh sesi, jadi kami akan menggunakan penyimpanan lokal .
Setiap bagian data disimpan dalam pasangan kunci/nilai. Kami akan menggunakan teks yang menghasilkan QR sebagai kunci dan gambar QR yang dikodekan sebagai string base64 sebagai nilainya. Buat folder entitas, di dalam folder buat file qr-object.ts baru dan tambahkan cuplikan kode seperti yang ditunjukkan:
Isi kelas:
export class QR { text: string; imageBase64: string; constructor(text: string, imageBase64: string) { this.imageBase64 = imageBase64; this.text = text; } }
Setiap kali pengguna menyimpan QR yang dihasilkan, kami akan membuat objek dari kelas di atas dan menyimpan objek itu menggunakan layanan utilitas penyimpanan.
Buat folder layanan baru, kami akan membuat banyak layanan, lebih baik mengelompokkannya.
Ubah direktori kerja saat ini menjadi services, cd services
, untuk membuat layanan baru gunakan ng gs <any name>
. Ini adalah singkatan untuk ng generate service <any name>
, ketik ng gs storageutil
dan tekan enter
Ini akan membuat dua file:
- storageutil.service.ts
- storageutil.service.spec.ts
Yang terakhir adalah untuk menulis unit test. Buka storageutil.service.ts dan tambahkan ini:
private historyCount: number; constructor() { } saveHistory(key : string, item :string) { localStorage.setItem(key, item) this.historyCount = this.historyCount + 1; } readHistory(key : string) : string { return localStorage.getItem(key) } readAllHistory() : Array<QR> { const qrList = new Array<QR>(); for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); const value = localStorage.getItem(key); if (key && value) { const qr = new QR(key, value); qrList.push(qr); } } this.historyCount = qrList.length; return qrList; } getHistoryCount(): number { if (this.historyCount) { return this.historyCount; } this.readAllHistory(); return this.historyCount; } deleteHistory(key : string) { localStorage.removeItem(key) this.historyCount = this.historyCount - 1; }
Impor kelas objek qr untuk memperbaiki kesalahan apa pun. Untuk menggunakan fitur penyimpanan lokal, tidak perlu mengimpor sesuatu yang baru cukup gunakan kata kunci localStorage
untuk menyimpan atau mendapatkan nilai berdasarkan kunci.
Sekarang buka file profile.component.ts lagi dan impor kelas StorageutilService
untuk menyelesaikan komponen profil dengan benar.
Menjalankan proyek, kita dapat melihat beranda sudah sesuai rencana.
Menambahkan Buat Halaman QR
Kami telah menyiapkan beranda kami, meskipun tombol buat/tambah tidak melakukan apa pun. Jangan khawatir, logika sebenarnya sudah ditulis. Kami menggunakan direktif routerLink
untuk mengubah jalur dasar URL ke /create
tetapi tidak ada pemetaan yang ditambahkan ke file app-routing.module.ts .
Mari buat komponen yang akan menangani pembuatan kode QR baru, ketik ng gc create-qr
dan tekan enter untuk menghasilkan komponen baru.
Buka file app-routing.module.ts dan tambahkan entri di bawah ini ke array routes
:
{ path: 'create', component: CreateQrComponent },
Ini akan memetakan CreateQRComponent
dengan URL /create
.
Buka create-qr.components.html dan ganti isinya dengan ini:
<app-header [showBackButton]="showBackButton" [currentTitle]="title" [showHistoryNav]="showHistoryNav"></app-header> <mat-card class="qrCard" [class.mat-elevation-z12]=true> <div class="qrContent"> <!--Close button section--> <div class="closeBtn"> <button mat-icon-button color="accent" routerLink="/" matTooltip="Close"> <mat-icon> <i class="material-icons md-48">close</i> </mat-icon> </button> </div> <!--QR code image section--> <div class="qrImgDiv"> <img *ngIf="!showProgressSpinner" src={{qrCodeImage}} width="200px" height="200px"> <mat-spinner *ngIf="showProgressSpinner"></mat-spinner> <div class="actionButtons" *ngIf="!showProgressSpinner"> <button mat-icon-button color="accent" matTooltip="Share this QR"> <mat-icon> <i class="material-icons md-48">share</i> </mat-icon> </button> <button mat-icon-button color="accent" (click)="saveQR()" matTooltip="Save this QR"> <mat-icon> <i class="material-icons md-48">save</i> </mat-icon> </button> </div> </div> <!--Textarea to write any text or link--> <div class="qrTextAreaDiv"> <mat-form-field> <textarea matInput [(ngModel)]="qrText" cdkTextareaAutosize cdkAutosizeMinRows="4" cdkAutosizeMaxRows="4" placeholder="Enter a website link or any text..."></textarea> </mat-form-field> </div> <!--Create Button--> <div class="createBtnDiv"> <button class="createBtn" mat-raised-button color="accent" matTooltip="Create new QR code" matTooltipPosition="above" (click)="createQrCode()">Create</button> </div> </div> </mat-card>
Cuplikan di atas menggunakan banyak elemen pustaka material Angular. Seperti yang direncanakan, ia memiliki satu referensi komponen header di mana parameter yang diperlukan dilewatkan. Selanjutnya adalah bagian utama dari halaman buat; ini terdiri dari satu kartu material Angular atau mat-card
dipusatkan dan ditinggikan hingga 12px karena [class.mat-elevation-z12]=true
digunakan.
Kartu materi hanyalah jenis wadah lain yang dapat digunakan sebagai tag div
lainnya. Meskipun pustaka materi menyediakan beberapa properti untuk meletakkan informasi yang terdefinisi dengan baik dalam mat-card
seperti penempatan gambar, judul, subjudul, deskripsi dan tindakan seperti yang dapat dilihat di bawah ini.
Dalam cuplikan HTML di atas, kami telah menggunakan mat-card
sama seperti wadah lainnya. Elemen library material lain yang digunakan adalah matTooltip
; itu hanyalah tooltip lain dengan kemudahan penggunaan, ditampilkan saat pengguna mengarahkan kursor atau menekan lama suatu elemen. Cukup gunakan cuplikan di bawah ini untuk menampilkan tooltip:
matTooltip="Any text you want to show"
Ini dapat digunakan dengan tombol ikon atau elemen UI lainnya untuk menyampaikan informasi tambahan. Dalam konteks aplikasi, ini menampilkan informasi tentang tombol ikon tutup. Untuk mengubah penempatan tooltip, matTooltipPosition
digunakan:
matTooltip="Any text you want to show" matTooltipPosition="above"
Selain matTooltip
, mat-spinner
digunakan untuk menunjukkan kemajuan pemuatan. Ketika pengguna mengklik tombol "Buat", panggilan jaringan dilakukan. Ini adalah saat pemintal kemajuan ditampilkan. Ketika panggilan jaringan kembali dengan hasil, kami hanya menyembunyikan pemintal. Ini dapat digunakan hanya seperti ini:
<mat-spinner *ngIf="showProgressSpinner"></mat-spinner>
showProgressSpinner
adalah variabel Boolean yang digunakan untuk menampilkan/menyembunyikan pemintal kemajuan. Pustaka juga menyediakan beberapa parameter lain seperti [color]='accent'
untuk mengubah warna, [mode]='indeterminate'
untuk mengubah jenis pemintal kemajuan. Pemintal kemajuan tak tentu tidak akan menunjukkan kemajuan tugas sementara yang pasti dapat memiliki nilai yang berbeda untuk mencerminkan kemajuan tugas. Di sini, pemintal tak tentu digunakan karena kami tidak tahu berapa lama panggilan jaringan akan berlangsung.
Pustaka materi menyediakan varian textarea yang sesuai dengan pedoman materi tetapi hanya dapat digunakan sebagai turunan dari mat-form-field
. Penggunaan material textarea sama sederhananya dengan HTML default, seperti di bawah ini:
<mat-form-field> <textarea matInput placeholder="Hint text"></textarea> </mat-form-field>
matInput
adalah arahan yang memungkinkan tag input
asli bekerja dengan mat-form-field
. Properti placeholder
memungkinkan menambahkan teks petunjuk apa pun untuk pengguna.
TIPS : Gunakan properti textarea cdkTextareaAutosize
untuk membuatnya dapat diubah ukurannya secara otomatis. Gunakan cdkAutosizeMinRows
dan cdkAutosizeMaxRows
untuk mengatur baris dan kolom dan ketiganya bersama-sama untuk membuat textarea auto-resize hingga mencapai batas maksimum baris dan kolom yang ditetapkan.
Untuk menggunakan semua elemen pustaka material ini, kita perlu menambahkannya di file app.module.ts .
Ada gambar placeholder yang digunakan dalam HTML. Unduh dan simpan ke folder /assets
.
HTML di atas juga memerlukan penataan CSS, jadi buka file create-qr.component.ts dan tambahkan yang berikut:
.qrCard { display: flex; flex-direction: column; align-items: center; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 20%; height: 65%; padding: 50px 20px; } .qrContent { display: flex; flex-direction: column; align-items: center; width: 100%; } .qrTextAreaDiv { width: 100%; display: flex; flex-direction: row; justify-content: center; padding: 0px 0px; position: absolute; bottom: 10%; } .createBtn { left: 50%; transform: translate(-50%, 0px); width: 80%; } .createBtnDiv { position: absolute; bottom: 5%; width: 100%; } .closeBtn { display: flex; flex-direction: row-reverse; align-items: flex-end; width: 100%; margin-bottom: 20px; } .closeBtnFont { font-size: 32px; color: rgba(0,0,0,0.75); } .qrImgDiv { top: 20%; position: absolute; display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; } .actionButtons { display: flex; flex-direction: row; padding-top: 20px; }
Mari kita pasang UI dengan logika. Buka file create-qr.component.ts dan tambahkan kode di bawah ini, biarkan baris yang sudah ada:
export class CreateQrComponent implements OnInit { qrCodeImage = '../../../assets/download.png'; showProgressSpinner = false; qrText: string; currentQR; showBackButton = true; title = 'Generate New QR Code'; showHistoryNav = true; constructor(private snackBar: MatSnackBar, private restutil: RestutilService, private storageService: StorageutilService) { } ngOnInit() { } createQrCode() { //Check if any value is given for the qr code text if (!!this.qrText) { //Make the http call to load qr code this.loadQRCodeImage(this.qrText); } else { //Show snackbar this.showSnackbar('Enter some text first') } } public loadQRCodeImage(text: string) { // Show progress spinner as the request is being made this.showProgressSpinner = true; // Trigger the API call this.restutil.getQRCode(text).subscribe(image =>{ // Received the result - as an image blob - require parsing this.createImageBlob(image); }, error => { console.log('Cannot fetch QR code from the url', error) // Hide the spinner - show a proper error message this.showProgressSpinner = false; }); } private createImageBlob(image: Blob) { // Create a file reader to read the image blob const reader = new FileReader(); // Add event listener for "load" - invoked once the blob reading is complete reader.addEventListener('load', () => { this.qrCodeImage = reader.result.toString(); //Hide the progress spinner this.showProgressSpinner = false; this.currentQR = reader.result.toString(); }, false); // Read image blob if it is not null or undefined if (image) { reader.readAsDataURL(image); } } saveQR() { if (!!this.qrText) { this.storageService.saveHistory(this.qrText, this.currentQR); this.showSnackbar('QR saved') } else { //Show snackbar this.showSnackbar('Enter some text first') } } showSnackbar(msg: string) { //Show snackbar this.snackBar.open(msg, '', { duration: 2000, }); } }
Untuk memberikan informasi kontekstual kepada pengguna, kami juga menggunakan MatSnackBar
dari pustaka desain material. Ini muncul sebagai popup dari bawah layar dan tetap selama beberapa detik sebelum menghilang. Ini bukan elemen melainkan layanan yang dapat dipanggil dari kode TypeScript.
Cuplikan di atas dengan nama metode showSnackbar
menunjukkan cara membuka snackbar, tetapi sebelum dapat digunakan, kita perlu menambahkan entri MatSnackBar
di file app.module.ts seperti yang kita lakukan untuk elemen pustaka material lainnya.
TIPS : Dalam versi pustaka material Angular terbaru, tidak ada cara langsung untuk mengubah gaya snackbar. Sebagai gantinya, kita harus membuat dua tambahan pada kode.
Pertama, gunakan CSS di bawah ini untuk mengubah warna latar belakang dan latar depan:
::ng-deep snack-bar-container.snackbarColor { background-color: rgba(63, 81, 181, 1); } ::ng-deep .snackbarColor .mat-simple-snackbar { color: white; }
Kedua, gunakan properti yang disebut panelClass
untuk mengatur gaya ke kelas CSS di atas:
this.snackBar.open(msg, '', { duration: 2000, panelClass: ['snackbarColor'] });
Dua kombinasi di atas akan memungkinkan penataan kustom ke komponen snackbar perpustakaan desain material.
Ini melengkapi langkah-langkah tentang cara membuat halaman QR, tetapi ada satu bagian yang masih hilang. Memeriksa file create-qr.component.ts , itu akan menunjukkan kesalahan tentang bagian yang hilang. Bagian yang hilang dari teka-teki ini adalah RestutilService
yang bertanggung jawab untuk mengambil gambar kode QR dari API pihak ketiga.
Di terminal, ubah direktori saat ini ke layanan dengan mengetik ng gs restutil
dan menekan Enter. Ini akan membuat file RestUtilService. Buka file restutil.service.ts dan tambahkan cuplikan ini:
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' }); }
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' }); }
Layanan di atas mengambil gambar QR dari API pihak ketiga dan karena responsnya bukan tipe JSON, tetapi gambar, jadi kami menetapkan responseType
sebagai 'blob'
dalam cuplikan di atas.
Angular menyediakan kelas HttpClient
untuk berkomunikasi dengan server pendukung HTTP apa pun. Ini menyediakan banyak fitur seperti memfilter permintaan sebelum dipecat, mendapatkan kembali respons, memungkinkan pemrosesan respons melalui panggilan balik dan lainnya. Untuk menggunakan yang sama, tambahkan entri untuk HttpClientModule di file app.module.ts .
Terakhir, impor layanan ini ke file create-qr.component.ts untuk menyelesaikan pembuatan kode QR.
Tapi tunggu! Ada masalah dengan pembuatan logika QR di atas. Jika pengguna menggunakan teks yang sama untuk menghasilkan QR lagi dan lagi, itu akan menghasilkan panggilan jaringan. Salah satu cara untuk mengatasi ini adalah caching berdasarkan permintaan, sehingga melayani respons dari cache jika teks permintaannya sama.
Permintaan Caching
Angular menyediakan cara sederhana untuk membuat panggilan HTTP, HttpClient, bersama dengan HttpInterceptors untuk memeriksa dan mengubah permintaan atau tanggapan HTTP ke dan dari server. Ini dapat digunakan untuk otentikasi atau caching dan banyak hal seperti itu, beberapa pencegat dapat ditambahkan dan dirantai untuk diproses lebih lanjut. Dalam hal ini, kami mencegat permintaan dan melayani respons dari cache jika teks QR sama.
Buat folder interseptor, lalu buat file cache-interceptor.ts :
Tambahkan cuplikan kode di bawah ini ke 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<any>>(); constructor() { } intercept(req: HttpRequest , next: HttpHandler): Observable<HttpEvent<any>> { 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); } })) } }
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<any>>(); constructor() { } intercept(req: HttpRequest , next: HttpHandler): Observable<HttpEvent<any>> { 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); } })) } }
Dalam cuplikan kode di atas, kami memiliki peta dengan kunci sebagai URL permintaan, dan respons sebagai nilainya. Kami memeriksa apakah URL saat ini ada di peta; 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 the 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, the History page.
Adding The History Page
All the saved QR codes will be visible here. To create another component, open terminal type ng gc 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:
<app-header [showBackButton]="showBackButton" [currentTitle]="title" [showHistoryNav]="showHistoryNav"></app-header> <div class="main-content"> <mat-grid-list cols="4" rowHeight="500px" *ngIf="historyList.length > 0"> <mat-grid-tile *ngFor="let qr of historyList"> <mat-card> <img mat-card-image src="{{qr.imageBase64}}"> <mat-card-content> <div class="truncate"> {{qr.text}} </div> </mat-card-content> <mat-card-actions> <button mat-button (click)="share(qr.text)">SHARE</button> <button mat-button color="accent" (click)="delete(qr.text)">DELETE</button> </mat-card-actions> </mat-card> </mat-grid-tile> </mat-grid-list> <div class="center-img" *ngIf="historyList.length == 0"> <img src="../../assets/no-see.png" width="256" height="256"> <span>Nothing to see here</span> </div> </div>
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.
Daftar kisi-kisi tikar bertindak sebagai wadah dengan beberapa anak ubin yang disebut mat-grid-tile
. Dalam cuplikan HTML di atas, setiap ubin dibuat menggunakan mat-card
menggunakan beberapa propertinya untuk penempatan umum elemen UI lainnya. Kami dapat memberikan number of columns
dan rowHeight
, yang digunakan untuk menghitung lebar secara otomatis. Dalam cuplikan di atas, kami menyediakan jumlah kolom dan nilai rowHeight
.
Kami menggunakan gambar placeholder saat riwayat kosong, unduh dan tambahkan ke folder aset.
Untuk menerapkan logika untuk mengisi semua informasi ini, buka file history.component.ts dan tambahkan cuplikan di bawah ini ke dalam kelas HistoryComponent
:
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,}) }
Logika di atas hanya mengambil semua QR yang disimpan dan mengisi halaman dengannya. Pengguna dapat menghapus QR yang disimpan yang akan menghapus entri dari penyimpanan lokal.
Jadi ini mengakhiri komponen sejarah kita... atau benarkah? Kita masih perlu menambahkan pemetaan rute untuk komponen ini. Buka app-routing.module.ts dan tambahkan pemetaan untuk halaman riwayat juga:
{ path: 'history', component: HistoryComponent },
Seluruh array rute akan terlihat seperti ini sekarang:
const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'create', component: CreateQrComponent }, { path: 'history', component: HistoryComponent }, ];
Sekarang adalah saat yang tepat untuk menjalankan aplikasi untuk memeriksa aliran lengkap, jadi buka terminal dan ketik ng serve
dan tekan Enter. Kemudian, buka localhost:4200
untuk memverifikasi kerja aplikasi.
Tambahkan Ke GitHub
Sebelum melanjutkan ke langkah penerapan, sebaiknya tambahkan proyek ke repositori GitHub.
- Buka GitHub.
- Buat repositori baru.
- Dalam Kode VS, gunakan terminal dan ikuti rangkaian perintah pertama yang disebutkan dalam panduan memulai cepat untuk mendorong semua file proyek.
Cukup segarkan halaman untuk memeriksa apakah semua file terlihat. Mulai saat ini, setiap perubahan git (seperti komit, tarik/dorong) akan tercermin dalam repositori yang baru dibuat ini.
Netlify dan Deployment
Aplikasi kami berjalan di mesin lokal kami, tetapi untuk memungkinkan orang lain mengaksesnya, kami harus menerapkannya di platform cloud dan mendaftarkannya ke nama domain. Di sinilah Netlify berperan. Ini menyediakan layanan penyebaran berkelanjutan, integrasi dengan GitHub, dan banyak lagi fitur yang dapat dimanfaatkan. Saat ini, kami ingin mengaktifkan akses global ke aplikasi kami. Mari kita mulai.
- Daftar di Netlify.
- Dari dasbor, klik tombol Situs baru dari Git .
- Klik GitHub di layar berikutnya.
- Otorisasi Netlify untuk dapat mengakses repositori GitHub Anda.
- Cari dan pilih repositori
qr
yang baru dibuat. - Netlify, pada langkah berikutnya, memungkinkan kita untuk memilih cabang repositori GitHub untuk penerapan. Biasanya seseorang menggunakan cabang
master
tetapi seseorang juga dapat memiliki cabangrelease
terpisah yang hanya berisi fitur terkait rilis dan stabil.
Karena ini adalah aplikasi web Angular, tambahkan ng build --prod
sebagai perintah build. Direktori yang diterbitkan akan dist/qr
seperti yang disebutkan dalam file angular.json
.
Sekarang klik tombol Deploy site
yang akan memicu pembangunan proyek dengan perintah ng build --prod
dan akan menampilkan file ke dist/qr
.
Karena kami memberikan informasi jalur ke Netlify, Netlify akan secara otomatis mengambil file yang benar untuk melayani aplikasi web. Netlify menambahkan domain acak ke aplikasi kita secara default.
Anda sekarang dapat mengklik tautan yang disediakan di halaman di atas untuk mengakses aplikasi dari mana saja. Akhirnya, aplikasi telah dikerahkan.
Domain Khusus
Pada gambar di atas, URL untuk aplikasi kita ditampilkan sementara sub-domain dibuat secara acak. Mari kita ubah itu.
Klik tombol Domain settings
lalu pada bagian Custom Domains klik menu 3 titik dan pilih Edit site name
.
Ini akan membuka popup di mana nama situs baru dapat dimasukkan; nama ini harus unik di seluruh domain Netlify. Masukkan nama situs apa pun yang tersedia dan klik Simpan .
Sekarang tautan ke aplikasi kami akan diperbarui dengan nama situs baru.
Pengujian Terpisah
Fitur keren lainnya yang ditawarkan Netlify adalah split testing. Ini memungkinkan pemisahan lalu lintas sehingga kumpulan pengguna yang berbeda akan berinteraksi dengan penerapan aplikasi yang berbeda. Kami dapat menambahkan fitur baru ke cabang yang berbeda dan membagi lalu lintas ke penyebaran cabang ini, menganalisis lalu lintas dan kemudian menggabungkan cabang fitur dengan cabang penyebaran utama. Mari kita konfigurasikan.
Prasyarat untuk mengaktifkan pengujian terpisah adalah repositori GitHub dengan setidaknya dua cabang. Buka repositori aplikasi di GitHub yang telah dibuat sebelumnya, dan buat cabang baru a
.
Repositori sekarang akan memiliki cabang master
dan a
. Netlify perlu dikonfigurasi untuk melakukan penyebaran cabang, jadi buka dasbor Netlify dan klik Settings
. Di sisi kiri, klik Build & Deploy
, lalu Continuous Deployment
, lalu di sisi kanan di bagian Deploy contexts
, klik Edit settings
.
Di sub-bagian Branch deploys
, pilih opsi "Biarkan saya menambahkan cabang individu", dan masukkan nama cabang dan simpan.
Menyebarkan brance adalah fitur berguna lainnya yang disediakan oleh Netlify; kita dapat memilih cabang repositori GitHub mana yang akan digunakan, dan kita juga dapat mengaktifkan pratinjau untuk setiap permintaan tarik ke cabang master
sebelum menggabungkan. Ini adalah fitur rapi yang memungkinkan pengembang untuk benar-benar menguji perubahan mereka secara langsung sebelum menambahkan perubahan kode mereka ke cabang penerapan utama.
Sekarang, klik opsi tab Split Testing
di bagian atas halaman. Konfigurasi pengujian terpisah akan disajikan di sini.
Kita dapat memilih cabang (selain cabang produksi) — dalam hal ini a
. Kita juga bisa bermain-main dengan pengaturan splitting traffic. Berdasarkan persentase lalu lintas setiap cabang telah dialokasikan, Netlify akan merutekan ulang beberapa pengguna ke aplikasi yang disebarkan menggunakan a
dan yang lainnya ke cabang master
. Setelah mengonfigurasi, klik tombol Start test
untuk mengaktifkan pemisahan lalu lintas.
TIPS : Netlify mungkin tidak mengenali bahwa repositori GitHub yang terhubung memiliki lebih dari satu cabang dan mungkin memberikan kesalahan ini:
Untuk mengatasi ini, cukup sambungkan kembali ke repositori dari opsi Build & Deploy
.
Netlify juga menyediakan banyak fitur lainnya. Kami baru saja membahas beberapa fitur bergunanya untuk menunjukkan kemudahan dalam mengonfigurasi berbagai aspek Netlify.
Ini membawa kita ke akhir perjalanan kita. Kami telah berhasil membuat desain Angular Material berdasarkan aplikasi web dan menerapkannya di Netlify.
Kesimpulan
Angular adalah kerangka kerja yang hebat dan populer untuk pengembangan aplikasi web. Dengan perpustakaan desain material Angular resmi, jauh lebih mudah untuk membuat aplikasi yang mematuhi spesifikasi desain material untuk interaksi yang sangat alami dengan pengguna. Selain itu, aplikasi yang dikembangkan dengan kerangka kerja yang hebat harus menggunakan platform yang hebat untuk penyebaran, dan Netlify hanya itu. Dengan evolusi yang konstan, dukungan yang hebat dan dengan banyak fitur, ini pasti merupakan platform yang hebat untuk membawa aplikasi web atau situs statis ke massa. Mudah-mudahan, artikel ini akan memberikan bantuan dalam memulai proyek Angular baru dari sekadar pemikiran hingga penerapan.
Bacaan lebih lanjut
- Arsitektur Sudut
- Lebih Banyak Komponen Material Sudut
- Lebih Banyak Tentang Fitur Netlify