สิทธิพิเศษทั้งหมด ไม่ยุ่งยาก: บทช่วยสอน Angular 9

เผยแพร่แล้ว: 2022-03-11

“ทุกๆ ปีอินเทอร์เน็ตล่ม” กล่าวโดยนักพัฒนามักจะต้องไปแก้ไข ด้วย Angular เวอร์ชัน 9 ที่รอคอยมายาวนาน บางคนอาจคิดว่าสิ่งนี้จะมีผลบังคับใช้ และแอปที่พัฒนาในเวอร์ชันก่อนหน้าจะต้องผ่านกระบวนการย้ายข้อมูลครั้งใหญ่

แต่นั่นไม่ใช่กรณี! ทีม Angular ได้ออกแบบคอมไพเลอร์ใหม่ทั้งหมด ส่งผลให้บิลด์เร็วขึ้น รันการทดสอบเร็วขึ้น ขนาดบันเดิลที่เล็กลง และที่สำคัญที่สุดคือความเข้ากันได้แบบย้อนหลังกับเวอร์ชันเก่า ด้วย Angular 9 นักพัฒนาโดยทั่วไปจะได้รับสิทธิพิเศษทั้งหมดโดยไม่ต้องยุ่งยาก

ในบทช่วยสอน Angular 9 นี้ เราจะสร้างแอปพลิเคชัน Angular ตั้งแต่เริ่มต้น เราจะใช้คุณลักษณะล่าสุดของ Angular 9 และทำการปรับปรุงอื่นๆ ต่อไป

บทช่วยสอน Angular 9: การเริ่มต้นด้วยแอปพลิเคชันเชิงมุมใหม่

มาเริ่มกันที่ตัวอย่างโครงการ Angular ของเรา ขั้นแรก ให้ติดตั้ง CLI ของ Angular เวอร์ชันล่าสุด:

 npm install -g @angular/cli

เราสามารถตรวจสอบเวอร์ชัน Angular CLI ได้โดยใช้ ng version

ต่อไป มาสร้างแอปพลิเคชันเชิงมุมกัน:

 ng new ng9-app --create-application=false --strict

เรากำลังใช้สองอาร์กิวเมนต์ในคำสั่ง ng new ของเรา:

  • --create-application=false จะบอก CLI ให้สร้างไฟล์พื้นที่ทำงานเท่านั้น ซึ่งจะช่วยให้เราจัดระเบียบโค้ดได้ดียิ่งขึ้นเมื่อเราต้องการมีแอปมากกว่าหนึ่งแอปและหลายไลบรารี
  • --strict จะเพิ่มกฎที่เข้มงวดขึ้นเพื่อบังคับใช้การพิมพ์ TypeScript และความสะอาดของโค้ดมากขึ้น

ด้วยเหตุนี้ เราจึงมีโฟลเดอร์และไฟล์พื้นที่ทำงานพื้นฐาน

ภาพหน้าจอของ IDE ที่แสดงโฟลเดอร์ ng9-app ที่มี node_modules, .editorconfig, .gitignore, angular.json, package-lock.json, package.json, README.md, tsconfig.json และ tslint.json

ตอนนี้ มาเพิ่มแอปใหม่กัน ในการทำเช่นนั้น เราจะเรียกใช้:

 ng generate application tv-show-rating

เราจะได้รับแจ้ง:

 ? Would you like to share anonymous usage data about this project with the Angular Team at Google under Google's Privacy Policy at https://policies.google.com/privacy? For more details and how to change this setting, see http://angular.io/analytics. No ? Would you like to add Angular routing? Yes ? Which stylesheet format would you like to use? SCSS

ตอนนี้ หากเราเรียกใช้ ng serve เราจะเห็นแอปทำงานโดยใช้นั่งร้านเริ่มต้น

สกรีนช็อตของนั่งร้านของ Angular 9 พร้อมแจ้งว่า "แอปจัดอันดับรายการทีวีกำลังทำงาน!" นอกจากนี้ยังมีลิงก์ไปยังแหล่งข้อมูลและขั้นตอนถัดไป

หากเราเรียกใช้ ng build --prod เราจะเห็นรายการไฟล์ที่สร้างขึ้น

สกรีนช็อตของเอาต์พุต "ng build --prod" ของ Angular 9 เริ่มต้นด้วย "การสร้างบันเดิล ES5 สำหรับการโหลดส่วนต่าง ... " หลังจากนั้นจะแสดงรายการกลุ่มไฟล์ JavaScript หลายไฟล์ เช่น รันไทม์ โพลีฟิล และไฟล์หลัก โดยแต่ละไฟล์มีเวอร์ชัน -es2015 และ -es5 และไฟล์ CSS หนึ่งไฟล์ บรรทัดสุดท้ายระบุการประทับเวลา แฮช และรันไทม์ 23,881 มิลลิวินาที

เรามีสองเวอร์ชันสำหรับแต่ละไฟล์ ตัวหนึ่งเข้ากันได้กับเบราว์เซอร์รุ่นเก่า และอีกตัวรวบรวมการกำหนดเป้าหมายที่ ES2015 ซึ่งใช้ API ที่ใหม่กว่าและต้องการโพลีฟิลน้อยลงเพื่อทำงานบนเบราว์เซอร์

การปรับปรุงที่สำคัญอย่างหนึ่งของ Angular 9 คือขนาดมัด จากข้อมูลของทีม Angular คุณสามารถเห็นการลดลงถึง 40% สำหรับแอพขนาดใหญ่

สำหรับแอปที่สร้างขึ้นใหม่ ขนาดชุดจะค่อนข้างใกล้เคียงกับของ Angular 8 แต่เมื่อแอปของคุณเติบโตขึ้น คุณจะเห็นขนาดชุดรวมมีขนาดเล็กลงเมื่อเทียบกับเวอร์ชันก่อนหน้า

คุณลักษณะอื่นที่นำมาใช้ใน Angular 9 คือความสามารถในการเตือนเราหากไฟล์ CSS สไตล์คอมโพเนนต์ใด ๆ ที่ใหญ่กว่าเกณฑ์ที่กำหนดไว้

สกรีนช็อตของส่วน "งบประมาณ" ของไฟล์การกำหนดค่า Angular 9 JSON ที่มีสองอ็อบเจ็กต์ในอาร์เรย์ ออบเจ็กต์แรกมีการตั้งค่า "type" เป็น "initial" "maximumWarning" ตั้งค่าเป็น "2mb" และ "maximumError" ตั้งค่าเป็น "5mb" ออบเจ็กต์ที่สองมีการตั้งค่า "type" เป็น "anyComponentStyle" "maximumWarning" ตั้งค่าเป็น "6kb" และ "maximumError" ตั้งค่าเป็น "10kb"

ซึ่งจะช่วยให้เราตรวจจับการนำเข้ารูปแบบที่ไม่ดีหรือไฟล์รูปแบบส่วนประกอบขนาดใหญ่ได้

การเพิ่มแบบฟอร์มให้คะแนนรายการทีวี

ต่อไป เราจะเพิ่มแบบฟอร์มให้คะแนนรายการทีวี ก่อนอื่นเราจะติดตั้ง bootstrap และ ng-bootstrap :

 npm install bootstrap @ng-bootstrap/ng-bootstrap

การปรับปรุงอีกประการหนึ่งของ Angular 9 คือ i18n (การทำให้เป็นสากล) ก่อนหน้านี้ นักพัฒนาจะต้องเรียกใช้งานบิลด์เต็มรูปแบบสำหรับทุกสถานที่ในแอป Angular 9 ช่วยให้เราสร้างแอปเพียงครั้งเดียวและสร้างไฟล์ i18n ทั้งหมดในขั้นตอนหลังสร้าง ซึ่งช่วยลดเวลาในการสร้างได้อย่างมาก เนื่องจาก ng-bootstrap มีการพึ่งพา i18n เราจะเพิ่มแพ็คเกจใหม่ให้กับโครงการของเรา:

 ng add @angular/localize

ต่อไป เราจะเพิ่มธีม Bootstrap ให้กับ styles.scss ของแอปของเรา:

 @import "~bootstrap/scss/bootstrap";

และเราจะรวม NgbModule และ ReactiveFormsModule ใน AppModule ของเราบน app.module.ts :

 // ... import { ReactiveFormsModule } from '@angular/forms'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; @NgModule({ imports: [ // ... ReactiveFormsModule, NgbModule ], })

ต่อไป เราจะอัปเดต app.component.html ด้วยตารางพื้นฐานสำหรับแบบฟอร์มของเรา:

 <div class="container"> <div class="row"> <div class="col-6"> </div> </div> </div>

และสร้างองค์ประกอบแบบฟอร์ม:

 ng gc TvRatingForm

มาอัปเดต tv-rating-form.component.html และเพิ่มแบบฟอร์มเพื่อให้คะแนนรายการทีวี

 <form [formGroup]="form" (ngSubmit)="submit()" class="mt-3"> <div class="form-group"> <label>TV SHOW</label> <select class="custom-select" formControlName="tvShow"> <option *ngFor="let tvShow of tvShows" [value]="tvShow.name">{{tvShow.name}}</option> </select> </div> <div class="form-group"> <ngb-rating [max]="5" formControlName="rating"></ngb-rating> </div> <button [disabled]="form.invalid || form.disabled" class="btn btn-primary">OK</button> </form>

และ tv-rating-form.component.ts จะมีลักษณะดังนี้:

 // ... export class TvRatingFormComponent implements OnInit { tvShows = [ { name: 'Better call Saul!' }, { name: 'Breaking Bad' }, { name: 'Lost' }, { name: 'Mad men' } ]; form = new FormGroup({ tvShow: new FormControl('', Validators.required), rating: new FormControl('', Validators.required), }); submit() { alert(JSON.stringify(this.form.value)); this.form.reset(); } }

สุดท้าย มาเพิ่มแบบฟอร์มใน app.component.html :

 <!-- ... --> <div class="col-6"> <app-tv-rating-form></app-tv-rating-form> </div>

ณ จุดนี้ เรามีฟังก์ชัน UI พื้นฐานบางอย่าง ทีนี้ ถ้าเราเรียกใช้ ng serve อีกครั้ง เราจะเห็นมันในการดำเนินการ

ภาพหน้าจอของแอปบทช่วยสอน Angular 9 ที่แสดงแบบฟอร์มชื่อ "TV SHOW" โดยมีรายการดรอปดาวน์ที่แสดงรายการชื่อรายการจำนวนหนึ่ง เครื่องตรวจวัดดาว และปุ่มตกลง ในภาพเคลื่อนไหว ผู้ใช้เลือกรายการ เลือกการให้คะแนน จากนั้นคลิกปุ่มตกลง

ก่อนที่เราจะไปต่อ มาดูฟีเจอร์ใหม่ๆ ที่น่าสนใจของ Angular 9 ที่เพิ่มเข้ามาเพื่อช่วยดีบั๊กกันก่อน เนื่องจากเป็นงานทั่วไปในชีวิตประจำวันของเรา จึงคุ้มค่าที่จะรู้ว่าอะไรเปลี่ยนแปลงไปเพื่อทำให้ชีวิตของเราง่ายขึ้นเล็กน้อย

การดีบักด้วย Angular 9 Ivy

การปรับปรุงที่สำคัญอีกประการหนึ่งใน Angular 9 และ Angular Ivy คือประสบการณ์การดีบัก คอมไพเลอร์สามารถตรวจจับข้อผิดพลาดได้มากขึ้นและแสดงข้อผิดพลาดในลักษณะที่ "อ่านง่าย" มากขึ้น

มาดูการทำงานกัน ขั้นแรก เราจะเปิดใช้งานการตรวจสอบเทมเพลตใน tsconfig.json :

 { // ... "angularCompilerOptions": { "fullTemplateTypeCheck": true, "strictInjectionParameters": true, "strictTemplates": true } }

ตอนนี้ หากเราอัปเดตอาร์เรย์ tvShows และเปลี่ยน name เป็น title :

 tvShows = [ { title: 'Better call Saul!' }, { title: 'Breaking Bad' }, { title: 'Lost' }, { title: 'Mad men' } ];

…เราจะได้รับข้อผิดพลาดจากคอมไพเลอร์

สกรีนช็อตของเอาต์พุตคอมไพเลอร์ Angular 9/Angular Ivy พร้อมชื่อไฟล์และตำแหน่งโดยระบุว่า "ข้อผิดพลาด TS2339: คุณสมบัติ 'ชื่อ' ไม่มีอยู่ในประเภท '{ title: string; }' นอกจากนี้ยังแสดงบรรทัดของโค้ดที่เป็นปัญหาและขีดเส้นใต้การอ้างอิง ในกรณีนี้ในไฟล์ tv-rating-form.component.html ที่มีการกล่าวถึง tvShow.name หลังจากนั้น การอ้างอิงไปยังไฟล์ HTML นี้จะถูกโยงไปถึงไฟล์ TypeScript ที่เกี่ยวข้องและถูกเน้นในทำนองเดียวกัน

การตรวจสอบประเภทนี้จะช่วยป้องกันการพิมพ์ผิดและการใช้ TypeScript อย่างไม่ถูกต้อง

การตรวจสอบความถูกต้องของ Angular Ivy สำหรับ @Input()

การตรวจสอบที่ดีอีกอย่างที่เราได้รับคือ @Input() ตัวอย่างเช่น เราอาจเพิ่มสิ่งนี้ใน tv-rating-form.component.ts :

 @Input() title: string;

…และผูกไว้ใน app.component.html :

 <app-tv-rating-form [title]="title"></app-tv-rating-form>

…แล้วเปลี่ยน app.component.ts ดังนี้:

 // ... export class AppComponent { title = null; }

หากเราทำการเปลี่ยนแปลงทั้งสามนี้ เราจะได้รับข้อผิดพลาดประเภทอื่นจากคอมไพเลอร์

ภาพหน้าจอของเอาต์พุตคอมไพเลอร์ Angular 9/Angular Ivy ในรูปแบบที่คล้ายกับก่อนหน้านี้ โดยเน้นที่ app.component.html ด้วย "ข้อผิดพลาด TS 2322: ประเภท 'null' ไม่สามารถกำหนดให้พิมพ์ 'string'"

ในกรณีที่เราต้องการเลี่ยงผ่าน เรา สามารถ ใช้ $any() บนเทมเพลตเพื่อแปลงค่าเป็นค่า any และแก้ไขข้อผิดพลาด:

 <app-tv-rating-form [title]="$any(title)"></app-tv-rating-form>

วิธีที่ถูกต้องในการแก้ไขปัญหานี้คือการทำให้ title ในแบบฟอร์มเป็นโมฆะ:

 @Input() title: string | null ;

ExpressionChangedAfterItHasBeenCheckedError ใน Angular 9 Ivy

หนึ่งในข้อผิดพลาดที่น่ากลัวที่สุดในการพัฒนาเชิงมุมคือ ExpressionChangedAfterItHasBeenCheckedError โชคดีที่ Ivy ได้แสดงข้อผิดพลาดอย่างชัดเจน ทำให้ง่ายต่อการค้นหาว่าปัญหามาจากไหน

ดังนั้น เรามาแนะนำข้อผิดพลาด ExpressionChangedAfterItHasBeenCheckedError ในการทำเช่นนั้น ขั้นแรก เราจะสร้างบริการ:

 ng gs Title

ต่อไป เราจะเพิ่ม BehaviorSubject และวิธีการเข้าถึง Observable และปล่อยค่าใหม่

 export class TitleService { private bs = new BehaviorSubject < string > (''); constructor() {} get title$() { return this.bs.asObservable(); } update(title: string) { this.bs.next(title); } }

หลังจากนั้น เราจะเพิ่มสิ่งนี้ใน app.component.html :

 <!-- ... --> <div class="col-6"> <h2> {{title$ | async}} </h2> <app-tv-rating-form [title]="title"></app-tv-rating-form> </div>

และใน app.component.ts เราจะฉีด TitleService :

 export class AppComponent implements OnInit { // ... title$: Observable < string > ; constructor( private titleSvc: TitleService ) {} ngOnInit() { this.title$ = this.titleSvc.title$; } // ... }

สุดท้าย ใน tv-rating-form.component.ts เราจะฉีด TitleService และอัปเดตชื่อของ AppComponent ซึ่งจะส่งข้อผิดพลาด ExpressionChangedAfterItHasBeenCheckedError

 // ... constructor( private titleSvc: TitleService ) { } ngOnInit() { this.titleSvc.update('new title!'); }

ตอนนี้ เราสามารถเห็นข้อผิดพลาดโดยละเอียดในคอนโซล dev ของเบราว์เซอร์ แล้วการคลิกที่ app.component.html จะนำเราไปยังตำแหน่งที่เกิดข้อผิดพลาด

ภาพหน้าจอของคอนโซลนักพัฒนาซอฟต์แวร์ของเบราว์เซอร์ แสดงการรายงานข้อผิดพลาด ExpressionChangedAfterItHasBeenCheckedError ของ Angular Ivy สแต็กเทรซในข้อความสีแดงแสดงข้อผิดพลาด พร้อมด้วยค่าก่อนหน้าและปัจจุบัน และคำใบ้ ตรงกลางของการติดตามสแต็กเป็นบรรทัดเดียวที่ไม่อ้างอิงถึง core.js ผู้ใช้คลิกและถูกนำไปที่บรรทัด app.component.html ที่ทำให้เกิดข้อผิดพลาด

เราสามารถแก้ไขข้อผิดพลาดนี้ได้โดยปิดการเรียกบริการด้วย setTimeout :

 setTimeout(() => { this.titleSvc.update('new title!'); });

เพื่อทำความเข้าใจว่าทำไมข้อผิดพลาด ExpressionChangedAfterItHasBeenCheckedError จึงเกิดขึ้นและสำรวจความเป็นไปได้อื่น ๆ การโพสต์ของ Maxim Koretskyi ในหัวข้อนั้นควรค่าแก่การอ่าน

Angular Ivy ช่วยให้เราแสดงข้อผิดพลาดได้ชัดเจนขึ้นและช่วยบังคับให้พิมพ์ TypeScript ในโค้ดของเรา ในส่วนต่อไปนี้ เราจะพูดถึงสถานการณ์ทั่วไปบางส่วนที่เราจะใช้ประโยชน์จาก Ivy และการดีบัก

การเขียนการทดสอบสำหรับแอป Angular 9 ของเราพร้อมสายรัดส่วนประกอบ

ใน Angular 9 มีการแนะนำ API การทดสอบใหม่ที่เรียกว่า component harnesses แนวคิดเบื้องหลังคือการขจัดงานน่าเบื่อทั้งหมดที่จำเป็นในการโต้ตอบกับ DOM ทำให้ทำงานได้ง่ายขึ้นและมีเสถียรภาพมากขึ้นในการทำงาน

ส่วนประกอบสายรัด API รวมอยู่ในไลบรารี @angular/cdk ดังนั้นก่อนอื่นให้ติดตั้งในโครงการของเรา:

 npm install @angular/cdk

ตอนนี้ เราสามารถเขียนการทดสอบและใช้ประโยชน์จากสายรัดส่วนประกอบได้ ใน tv-rating-form.component.spec.ts มาตั้งค่าการทดสอบกัน:

 import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { ReactiveFormsModule } from '@angular/forms'; describe('TvRatingFormComponent', () => { let component: TvRatingFormComponent; let fixture: ComponentFixture < TvRatingFormComponent > ; beforeEach(async (() => { TestBed.configureTestingModule({ imports: [ NgbModule, ReactiveFormsModule ], declarations: [TvRatingFormComponent] }).compileComponents(); })); // ... });

ต่อไป มาใช้งาน ComponentHarness สำหรับส่วนประกอบของเรา เราจะสร้างสายรัดสองชุด: ชุดหนึ่งสำหรับ TvRatingForm และอีกชุดสำหรับ NgbRating ComponentHarness ต้องการฟิลด์ส static hostSelector ซึ่งควรใช้ค่าของตัวเลือกของส่วนประกอบ

 // ... import { ComponentHarness, HarnessLoader } from '@angular/cdk/testing'; import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; class TvRatingFormHarness extends ComponentHarness { static hostSelector = 'app-tv-rating-form'; } class NgbRatingHarness extends ComponentHarness { static hostSelector = 'ngb-rating'; } // ...

สำหรับ TvRatingFormHarness เราจะสร้างตัวเลือกสำหรับปุ่มส่งและฟังก์ชันเพื่อทริกเกอร์การ click คุณสามารถดูได้ว่าการดำเนินการนี้ง่ายขึ้นเพียงใด

 class TvRatingFormHarness extends ComponentHarness { // ... protected getButton = this.locatorFor('button'); async submit() { const button = await this.getButton(); await button.click(); } }

ต่อไป เราจะเพิ่มวิธีการกำหนดเรตติ้ง ที่นี่เราใช้ locatorForAll เพื่อค้นหาองค์ประกอบ <span> ทั้งหมดที่แสดงถึงดวงดาวที่ผู้ใช้สามารถคลิกได้ ฟังก์ชัน rate จะรับดาวของการให้คะแนนที่เป็นไปได้ทั้งหมด และคลิกที่ดาวที่สอดคล้องกับค่าที่ส่ง

 class NgbRatingHarness extends ComponentHarness { // ... protected getRatings = this.locatorForAll('span:not(.sr-only)'); async rate(value: number) { const ratings = await this.getRatings(); return ratings[value - 1].click(); } }

สิ่งสุดท้ายที่ขาดหายไปคือการเชื่อมต่อ TvRatingFormHarness กับ NgbRatingHarness ในการทำเช่นนั้น เราเพียงแค่เพิ่มตัวระบุตำแหน่งในคลาส TvRatingFormHarness

 class TvRatingFormHarness extends ComponentHarness { // ... getRating = this.locatorFor(NgbRatingHarness); // ... }

ทีนี้มาเขียนการทดสอบของเรากัน:

 describe('TvRatingFormComponent', () => { // ... it('should pop an alert on submit', async () => { spyOn(window, 'alert'); const select = fixture.debugElement.query(By.css('select')).nativeElement; select.value = 'Lost'; select.dispatchEvent(new Event('change')); fixture.detectChanges(); const harness = await TestbedHarnessEnvironment.harnessForFixture(fixture, TvRatingFormHarness); const rating = await harness.getRating(); await rating.rate(1); await harness.submit(); expect(window.alert).toHaveBeenCalledWith('{"tvShow":"Lost","rating":1}'); }); });

โปรดสังเกตว่าสำหรับการ select ของเราภายในแบบฟอร์ม เราไม่ได้ทำการตั้งค่าผ่านสายรัด นั่นเป็นเพราะว่า API ยังไม่รองรับการเลือกตัวเลือก แต่สิ่งนี้ทำให้เรามีโอกาสเปรียบเทียบว่าการโต้ตอบกับองค์ประกอบต่างๆ เป็นอย่างไรก่อนที่จะมีสายรัดส่วนประกอบ

สิ่งสุดท้ายก่อนที่เราจะทำการทดสอบ เราจำเป็นต้องแก้ไข app.component.spec.ts เนื่องจากเราอัปเดต title เป็น null

 describe('AppComponent', () => { // ... it(`should have as title 'tv-show-rating'`, () => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.componentInstance; expect(app.title).toEqual(null); }); });

ตอนนี้เมื่อเรารัน ng test ของเราจะผ่าน

สกรีนช็อตของ Karma ที่ทำการทดสอบบนแอพ Angular 9 ของเรา มันแสดง "Ran 2 จาก 6 specs" พร้อมข้อความ "Incomplete: fit() or fdescribe() found, 2 specs, 0 failures, randomized with seed 69573" การทดสอบสองครั้งของ TvRatingFormComponent ถูกเน้นไว้ การทดสอบสามรายการของ AppComponent และการทดสอบเดียวของ TitleService เป็นสีเทาทั้งหมด

กลับไปที่แอปตัวอย่าง Angular 9 ของเรา: การบันทึกข้อมูลในฐานข้อมูล

มาสรุปบทช่วยสอน Angular 9 ของเราโดยเพิ่มการเชื่อมต่อกับ Firestore และบันทึกการให้คะแนนในฐานข้อมูล

ในการทำเช่นนั้น เราต้องสร้างโปรเจ็กต์ Firebase จากนั้น เราจะติดตั้งการพึ่งพาที่จำเป็น

 npm install @angular/fire firebase

ในการตั้งค่าโปรเจ็กต์ของคอนโซล Firebase เราจะได้รับการกำหนดค่าและเพิ่มไปยัง environment.ts และ environment.prod.ts :

 export const environment = { // ... firebase: { apiKey: '{your-api-key}', authDomain: '{your-project-id}.firebaseapp.com', databaseURL: 'https://{your-project-id}.firebaseio.com', projectId: '{your-project-id}', storageBucket: '{your-project-id}.appspot.com', messagingSenderId: '{your-messaging-id}', appId: '{your-app-id}' } };

หลังจากนั้น เราจะนำเข้าโมดูลที่จำเป็นใน app.module.ts :

 import { AngularFireModule } from '@angular/fire'; import { AngularFirestoreModule } from '@angular/fire/firestore'; import { environment } from '../environments/environment'; @NgModule({ // ... imports: [ // ... AngularFireModule.initializeApp(environment.firebase), AngularFirestoreModule, ], // ... })

ต่อไป ใน tv-rating-form.component.ts เราจะฉีดบริการ AngularFirestore และบันทึกคะแนนใหม่ในการส่งแบบฟอร์ม:

 import { AngularFirestore } from '@angular/fire/firestore'; export class TvRatingFormComponent implements OnInit { constructor( // ... private af: AngularFirestore, ) { } async submit(event: any) { this.form.disable(); await this.af.collection('ratings').add(this.form.value); this.form.enable(); this.form.reset(); } } 

ภาพหน้าจอของแอปบทช่วยสอน Angular 9 ที่แสดงแบบฟอร์มชื่อ "TV SHOW" ใต้ชื่อหน้าที่ใหญ่กว่า "ชื่อใหม่!" อีกครั้ง มีรายการดรอปดาวน์ที่แสดงรายการชื่อรายการ จำนวนหนึ่ง เครื่องวัดดาว และปุ่มตกลง และอีกครั้งที่ผู้ใช้เลือกรายการ เลือกการให้คะแนน แล้วคลิกปุ่มตกลง

ตอนนี้ เมื่อเราไปที่คอนโซล Firebase เราจะเห็นรายการที่สร้างขึ้นใหม่

สกรีนช็อตของคอนโซล Firebase ในคอลัมน์ด้านซ้ายคือ joaq-lab ที่มีคอลเล็กชันบางส่วน ได้แก่ ผู้เข้าร่วม การแข่งขัน การให้คะแนน การทดสอบ และผู้ใช้ รายการการให้คะแนนถูกเลือกและแสดงอยู่ในคอลัมน์กลางโดยเลือกรหัสไว้ ซึ่งเป็นเอกสารเดียว คอลัมน์ทางขวาแสดงสองฟิลด์: "การให้คะแนน" ถูกตั้งค่าเป็น 4 และ "tvShow" ถูกตั้งค่าเป็น "คนบ้า"

สุดท้าย มาแสดงรายการการให้คะแนนทั้งหมดลงใน AppComponent ในการทำเช่นนั้น ใน app.component.ts เราจะได้รับข้อมูลจากการรวบรวม:

 import { AngularFirestore } from '@angular/fire/firestore'; export class AppComponent implements OnInit { // ... ratings$: Observable<any>; constructor( // ... private af: AngularFirestore ) { } ngOnInit() { // ... this.ratings$ = this.af.collection('ratings').valueChanges(); } }

…และใน app.component.html เราจะเพิ่มรายการการให้คะแนน:

 <div class="container"> <div class="row"> // ... <div class="col-6"> <div> <p *ngFor="let rating of ratings$ | async"> {{rating.tvShow}} ({{rating.rating}}) </p> </div> </div> </div> </div>

นี่คือลักษณะที่แอปบทช่วยสอน Angular 9 ของเราเมื่อรวมทุกอย่างเข้าด้วยกัน

ภาพหน้าจอของแอปบทช่วยสอน Angular 9 ที่แสดงแบบฟอร์มชื่อ "TV SHOW" ใต้ชื่อหน้าที่ใหญ่กว่า "ชื่อใหม่!" อีกครั้ง มีรายการดรอปดาวน์ที่แสดงรายการชื่อรายการ จำนวนหนึ่ง เครื่องวัดดาว และปุ่มตกลง คราวนี้ คอลัมน์ทางขวามือแสดงรายการ "คนบ้า (4)" และผู้ใช้ให้คะแนนแพ้สามดาว ตามด้วย "คนบ้า" อีกครั้งที่สี่ดาว คอลัมน์ทางขวามือยังคงเรียงลำดับตามตัวอักษรหลังจากการให้คะแนนใหม่ทั้งคู่

Angular 9 และ Angular Ivy: การพัฒนาที่ดีขึ้น แอพที่ดีขึ้น และความเข้ากันได้ที่ดีขึ้น

ในบทช่วยสอน Angular 9 นี้ เราได้กล่าวถึงการสร้างแบบฟอร์มพื้นฐาน การบันทึกข้อมูลไปยัง Firebase และการรับไอเท็มจากแบบฟอร์ม

ระหว่างทาง เราได้เห็นว่ามีการปรับปรุงและคุณลักษณะใหม่ใดบ้างที่รวมอยู่ใน Angular 9 และ Angular Ivy สำหรับรายการทั้งหมด คุณสามารถตรวจสอบโพสต์เผยแพร่ล่าสุดของบล็อก Angular อย่างเป็นทางการ


ป้าย Google Cloud Partner

ในฐานะ Google Cloud Partner ผู้เชี่ยวชาญที่ผ่านการรับรองจาก Google ของ Toptal พร้อมให้บริการสำหรับบริษัทต่างๆ ที่ต้องการสำหรับโครงการที่สำคัญที่สุดของพวกเขา