วันจันทร์ที่ 6 มกราคม พ.ศ. 2563

Angular 8 - แบ่ง Component เป็นหน้า ๆ กับ Router Module

ความเดิมจากตอนที่แล้วเราได้ทำการ Follow Guide หัวข้อ Your First App เสร็จแล้ว https://angular.io/start
ให้หัวข้อต่อมาเรื่องของ Routing https://angular.io/start/routing จะเริ่มสร้างหน้าย่อ ๆ กัน

ใช้ Code ต่อจากตอนที่แล้วเราจะทำการเพิ่ม RouterModule อย่างเดียวแล้วทำความเข้าใจกันก่อนว่ามันเป็นส่วนไหน
ให้เราทำการ Import Module ชื่อ "RouterModule" และทำการ Import และใส่ข้อมูล Path ด้วยใน "RouterModule.forRoot([])"
ส่วนของ path ใช่เป็น ' ' หมายถึง Root และแสดง Component ProductListComponent
src/app/app.modult.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
 
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
 
import { RouterModule } from '@angular/router';
 
import { TopBarComponent } from './top-bar/top-bar.component';
import { ProductListComponent } from './product-list/product-list.component';
import { ProductAlertsComponent } from './product-alerts/product-alerts.component';
 
 
@NgModule({
  declarations: [
    AppComponent,
    TopBarComponent,
    ProductListComponent,
    ProductAlertsComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    RouterModule.forRoot([
      { path: '', component: ProductListComponent }
    ]),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
 
export class AppModule { }
src/app/app.component.html
1
2
3
4
<app-top-bar></app-top-bar>
<app-product-list></app-product-list>
 
<router-outlet></router-outlet>

เมื่อ Run App เราจะเห็นว่ามี Product List 2 อันเรียกกันอยู่

อธิบาย
ไฟล์ "app.component.html" เป็นหน้าหลักที่ใช้ในการแสดงและ Tag "router-outlet" นั้นได้เอา ProductListComponent ขึ้นมาแสดงทำให้ซ้อนกัน
กับที่เราเพิ่ม Tag "app-product-list" ก่อนหน้านี้

ให้เราทำการลบ Tag "app-product-list" ออกแล้วกลับไปดูที่ App อีกครั้ง
src/app/app.component.html
1
2
3
4
5
<app-top-bar></app-top-bar>
<!-- ลบส่วนที่ Comment นี้ -->
<!--app-product-list></app-product-list-->
 
<router-outlet></router-outlet>



เราจะทำการสร้างหน้า ProductDetail ตาม Guide Routing โดนเราจะสร้าง Component ProductDetail แล้วทดสอบ Link ไปว่าทำงานได้ไหม

สร้าง Component ชื่อ ProductDetail ผ่านคำสั่ง ng แบบนี้ "ng generate component product-detail"
แล้วแก้ไข RouterModule ทำการเพิ่ม path ไปยัง "product-detail" และแก้ไข ProductList โดยเมื่อกดที่ชื่อมือถือให้ไปยังหน้า ProductDetail
ใช้ [routerLink]="['path']" | อ่านเพิ่มเติมได้ที่ https://angular.io/api/router/RouterLink
src/app/app.modult.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
 
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
 
import { RouterModule } from '@angular/router';
 
import { TopBarComponent } from './top-bar/top-bar.component';
import { ProductListComponent } from './product-list/product-list.component';
import { ProductAlertsComponent } from './product-alerts/product-alerts.component';
 
 
@NgModule({
  declarations: [
    AppComponent,
    TopBarComponent,
    ProductListComponent,
    ProductAlertsComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    RouterModule.forRoot([
      { path: '', component: ProductListComponent },
      { path: 'product', component: ProductDetailComponent }
    ]),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
 
export class AppModule { }
src/app/product-list/product-list.component.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<h1>{{title}}</h1>
 
<div *ngFor="let product of productList">
    <a [title]="'Description: ' + product.description" [routerLink]="['/product']">
        {{product.name}}
    </a>
 
    <p *ngIf="product.description">
        {{product.description}}
    </p>
 
    <button (click)="share()">
        Share
    </button>
 
    <app-product-alerts [product]="product" (notify)="onNotify()"></app-product-alerts>
 
</div>

ทำการทดสอบโดยการคลิกที่ Link ชื่อมือถือจะส่งไปยังหน้า ProductDetail



การส่งค่าไปพร้อมกับ Link ด้วย ให้เราทำการแก้ไขส่วนของ RouterModule ส่วนของ path ให้เพิ่ม /:productId เพื่อบอกว่าจะรับ Product Id ต่อจาก /
และทำการแก้ไขส่วนของ ProductList เพิ่มส่วนของ RouterLink ให้เพิ่ม productId มาด้วย
src/app/app.modult.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
 
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
 
import { RouterModule } from '@angular/router';
 
import { TopBarComponent } from './top-bar/top-bar.component';
import { ProductListComponent } from './product-list/product-list.component';
import { ProductAlertsComponent } from './product-alerts/product-alerts.component';
 
 
@NgModule({
  declarations: [
    AppComponent,
    TopBarComponent,
    ProductListComponent,
    ProductAlertsComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    RouterModule.forRoot([
      { path: '', component: ProductListComponent },
      { path: 'product/:productId', component: ProductDetailComponent }
    ]),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
 
export class AppModule { }
src/app/product-list/product-list.component.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<h1>{{title}}</h1>
 
<div *ngFor="let product of productList; index as productId">
    <a [title]="'Description: ' + product.description" [routerLink]="['/product', productId]">
        {{product.name}}
    </a>
 
    <p *ngIf="product.description">
        {{product.description}}
    </p>
 
    <button (click)="share()">
        Share
    </button>
 
    <app-product-alerts [product]="product" (notify)="onNotify()"></app-product-alerts>
 
</div>
สังเกตุที่ URL จะมี ProductId ติดมาด้วย


การรับค่าไปใช้งานต่อใน ProductDetail เราจะใช้ https://angular.io/guide/lifecycle-hooks
ทำการเพิ่ม Code ในส่วนของ ngOnInit() {} โดยเรียก this.route.paramMap.subscribe(params => {})
ก่อนเรียกใช้งาน route ให้ทำการ Import ActivatedRoute [บรรทัดที่ 2] และรับ route ที่ Contructor [บรรทัดที่ 11] ด้วย

src/app/product-detail/product-detail.component.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
 
@Component({
  selector: 'app-product-detail',
  templateUrl: './product-detail.component.html',
  styleUrls: ['./product-detail.component.css']
})
export class ProductDetailComponent implements OnInit {
 
  constructor(private route: ActivatedRoute) { }
 
  ngOnInit() {
 
    this.route.paramMap.subscribe(params => {
      window.alert(params.get('productId'));
    });
 
  }
 
}



การดึงค่าออกมาแสดง โดยให้ทำการ Import products [บรรทัดที่ 4] เข้ามาก่อนจากนั้นเอา productId ไปเลือกว่าเป็น Product ตัวไหน [บรรทัดที่ 21]
แล้วกำหนดค่าให้กับ product ที่อยู่ใน ProductDetail และทำออกมาแสดงที่ Template
src/app/product-detail/product-detail.component.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
 
import { products } from '../products';
 
@Component({
  selector: 'app-product-detail',
  templateUrl: './product-detail.component.html',
  styleUrls: ['./product-detail.component.css']
})
export class ProductDetailComponent implements OnInit {
 
  product;
 
  constructor(private route: ActivatedRoute) { }
 
  ngOnInit() {
 
    this.route.paramMap.subscribe(params => {
      // window.alert(params.get('productId'));
      this.product = products[+params.get('productId')];
    });
 
  }
 
}
src/app/product-detail/product-detail.component.html
1
2
3
4
5
6
7
8
<h2>Product Details</h2>
 
<div *ngIf="product">
  <h3>{{ product.name }}</h3>
  <h4>{{ product.price | currency }}</h4>
  <p>{{ product.description }}</p>
 
</div>
จบแล้ว

ไม่มีความคิดเห็น:

แสดงความคิดเห็น