[Angular-Day 4] Thực hành component, directive và service

0
Bài này thuộc phần 4 của 4 phần trong series Học lập trình Angular từ A-Z

Ở phần trước, chúng ta đã tìm hiểu cách tạo một ứng dụng Angular, các thành phần cơ bản cũng như cấu trúc thư mục một dự án Angular.

Như đã hứa, trong bài viết hôm nay, chúng ta sẽ bắt tay vào implement các Angular component, directive and service để tạo ứng dụng MySpotify như mình đã giới thiệu.

😉 Đọc các bài viết khác về JS:

Tạo Angular Components

Bật ứng dụng Vscode và mở dự án mà bạn đã tạo ở phần trước. Đầu tiên, bạn tạo một file mới trong thư mục app, đặt tên là products.component.ts

angular-component

Bạn lưu ý quy ước đặt tên nhé. Thông thường, mình hay đặt tên component theo quy ước sau: <tên component>.component.ts. Trong đó ts là extension của các file sử dụng ngôn ngữ Typescript.

Sau đó, bạn viết code nội dung cho component này như này:

import { Component } from '@angular/core'
@Component({
    selector: 'products',
    template: '<h2>Products</h2>'
})
export class ProductsComponent {
}

😉 Giải thích một chút:

Trong đoạn code trên, chúng ta sử dụng phương pháp Object Destructuring để import Component từ core module  của Angular.

Hàm @Component sẽ nhận vào một object với hai tham số: selector và template (đều có kiểu là string). Trong đó, selector để bạn định nghĩa một css selector cho một host html element. Khi Angular nhìn thấy một element mà khớp với css selector này, nó sẽ tạo một instance của compoment này trong host element. Trong trường hợp này, host element của chúng ta là một element có tag là “products”.

Tiếp theo, template dùng để xác định mã html sẽ được chèn vào DOM khi component được hiển thị. Chúng ta có thể viết html dạng inline tại đây hoặc tham chiếu tới một file html riêng biệt bằng cách sử dụng thuộc tính templateUrl (tương tự như cách màn bạn thấy trong app.component.ts)

Cuối cùng, từ khóa export để component này có thể được sử dụng ở các file khác ứng dụng. Nếu bạn biết ES6 thì không còn lạ gì từ khóa export/import này nữa.

Ok, chỉ với một vài dòng code đơn giản như vậy là bạn đã tạo xong một component rồi.

Sử dụng Component

Tiếp theo, sau khi tạo xong products component, giả sử mình muốn sử dụng component này trong màn hình chính app.component.ts, bạn cần phải khai báo nó trong module trước.

Mở app.module.ts và khai báo product component như sau (phần mình bôi đậm):

import { AppComponent } from './app.component';
import { ProductsComponent } from './products.component';

@NgModule({
  declarations: [
    AppComponent, ProductsComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Sau đó quay trở lại app.component.ts và sử dụng thôi. Như trong ví dụ này, mình sẽ gọi product component trong thẻ template.

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template:
    `<h1>{{title}}</h1>
    <products></products>`,
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  title = 'VNTALKING xin chào cả nhà';
}

Ok, giờ kiểm tra lại giao diện ứng dụng: http://localhost:4200

angular component
angular component

Cũng đơn giản phải không? Hì.

Sử dụng Template

Bởi vì một component sẽ đóng gói dữ liệu và logic nên chúng ta có thể định nghĩa thuộc tính (properties) và hiển thị chúng trong template. Ví dụ như với AppComponent chúng ta định nghĩa thuộc tính title vậy.

export class AppComponent {
  title = 'VNTALKING xin chào cả nhà';
}

Hoặc chúng ta thử thêm một thuộc tính cho products component xem như nào nhé.

import { Component } from '@angular/core'
@Component({
    selector: 'products',
    template: '<h2>{{description}}</h2>'
})
export class ProductsComponent {
    description = "Sản phẩm tốt"
}

Kết quả:

angular-template

Interpolation

Cú pháp để render giá một thuộc tính trong template là sử dụng dấu ngoặc nhọn. Ví dụ: {{title}}

template:
    `<h1>{{title}}</h1>
    <products></products>`

Thực ra tính năng này không có gì đặc biệt hay độc quyền gì trên Angular cả. Thực chất nó là một tính năng của Javascript ES6 mà thôi.

Tính năng này gọi là interpolation, khi giá trị của thuộc tính thay đổi thì component tự động cập nhật theo, view sẽ tự động được refresh. Cách hoạt động này người ta hay gọi là binding một chiều. Sau này bạn còn gặp kiểu binding 2 chiều nữa, thường sử dụng trong form nhập liệu.

Hiển thị danh sách

Chúng ta sẽ minh họa thêm về cách sử dụng các thuộc tính trong component bằng cách thực hành hiển thị danh sách cách products trong ProductsComponent. Đầu tiên, chúng ta sẽ định nghĩa một mảng các products trong ProductsComponent.

Trong products.component.ts bạn sửa lại đoạn code như sau:

export class ProductsComponent {
    products = ["Học lập trình Angular miễn phí", "Tài liệu React tiếng việt", "Sách học lập trình NodeJS thật đơn giản", "VNTALKING.COM"];
}

Tiếp theo, trong template chúng ta sử dụng thẻ <ul> để hiển thị danh sách các products.

@Component({
    selector: 'products',
    template: `
        <h2>Products</h2>
        <ul>
            <li *ngFor="let product of products">{{product}}</li>
        </ul>`
})

Trong đó: *ngFor="let product of products" là mình đang thực hiện một vòng lặp để duyệt mảng nhé.

Bây giờ tận hưởng thành quả nhé.

angular-service

Về cơ bản thì nhìn template cũng tương tự với HTML mà bạn vẫn quen thuộc. Chỉ khác là chúng được bổ sung thêm các thuộc tính đặc biệt giúp bạn xử lý logic, ví dụ như *ngFor để duyệt mảng chẳng hạn.

Services và Dependency Injection

Hiện tại, các Angular component của chúng ta đang hiển thị một danh sách các products, trong đó dữ liệu là mình đang hardcode. Còn trong thực tế, dữ liệu có thể được lấy về từ REST API, các component chỉ nên chứa các login để hiển thị mà thôi. Còn logic để lấy dữ liệu từ server nên được đóng gói ở một nơi khác, đó là service.

Bây giờ, chúng ta thử tạo một service để giả lập việc lấy dữ liệu từ server nhé.

Trong thư mục app, tạo product.service.ts. Nên nhớ quy tắc đặt tên nhé, nếu là service thì sẽ có tiền tố service, còn component thì có tiền tố component… cái này mình chỉ nhắc lại thôi.

Ok, nội dùng của product.service.ts như sau:

export class ProductService {
    getProducts(): string[] {
        return ["Learning Angular 2", "Pro TypeScript", "ASP.NET"];
    }
}

Quay trở lại product.component.ts và sửa lại như sau:

import { Component } from '@angular/core'
import { ProductService } from './product.service';
@Component({
    selector: 'products',
    template: `
        <h2>Sản phẩm</h2>
        <ul>
            <li *ngFor="let product of products">{{product}}</li>
        </ul>`
})
export class ProductsComponent {
    products;
    constructor(productService: ProductService) {
        this.products = productService.getProducts();
    }
}

😉 Mình sẽ giải thích một chút:

Giờ dữ liệu mảng các products được chúng ta khởi tạo trong hàm constructor. Hàm contructor này nhận một đối tượng ProductService, từ đó chúng ta gọi tới hàm getProducts() để lấy dữ liệu.

Có thể bạn sẽ thắc mắc: Làm thế nào mà mình lại tạo Product service và truyền chúng vào được hàm contructor?

Đó là vì mình đang sử dụng phương pháp Dependency Injection được tích hợp sẵn trong Angular.

Tuy nhiên, viết đến đây thì code sẽ bị lỗi, lý do là chúng ta chưa inject trong app.component.ts. Phần mình bôi đậm chính là code cần phải thêm để inject ProductService nhé.

import { Component } from '@angular/core';
import { ProductService } from './product.service';

@Component({
  selector: 'app-root',
  template:
    `<h1>{{title}}</h1>
    <products></products>`,
  providers: [ProductService],
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  title = 'VNTALKING xin chào cả nhà';
}

Cuối cùng là hưởng thụ thành quả nhé. Thực tế thì bạn vẫn nhận được kết quả như cũ, chỉ là code bây giờ nó chuyên nghiệp hơn thôi J

Tạm kết

Hôm nay chúng ta tạm thời nghỉ tay tại đây. Qua phần này, chúng ta đã biết cách tạo và sử dụng Angular component, cũng như sử dụng service để giả lập lấy dữ liệu từ server.

Các bạn có thể lấy code minh họa của bài viết này tại đây.

Chúc bạn một buối tối vui vẻ.

Xem tiếp các bài trong Series
Phần trước: [Angular-Day 3] Cấu trúc dự án Angular và Typescript compilation
Dịch vụ phát triển ứng dụng mobile giá rẻ - chất lượng

Bình luận. Cùng nhau thảo luận nhé!

avatar
  Theo dõi bình luận  
Thông báo