12/08/2018, 16:53

Cùng tìm hiểu kiến trúc của Angular 2 và sự khác nhau về kiến trúc giữa Angular 1 và Angular 2

Một ứng dụng Angular được xây dựng từ 8 thành phần sau đây: Module, Component, Template, Metadata, Data Binding, Directive, Service, Dependency Injection. Mỗi ứng dụng Angular được gọi là một module và bản thân Angular có riêng một module dùng để quản lý các module khác có tên là Root Module ...

Một ứng dụng Angular được xây dựng từ 8 thành phần sau đây: Module, Component, Template, Metadata, Data Binding, Directive, Service, Dependency Injection.

Mỗi ứng dụng Angular được gọi là một module và bản thân Angular có riêng một module dùng để quản lý các module khác có tên là Root Module hay NgModule. Root Module thường được đặt tên là AppModule, ngoài root ra thì tùy ứng dụng mà sẽ có thêm các module khác, chúng ta sẽ tìm hiểu về root module trong bài sau.

Chúng ta khai báo một module bằng cách dùng từ khóa @NgModule. Các từ khóa như @NgModule này là các hàm dùng để chỉnh sửa các lớp của Javascript. Bên trong từ khóa @NgModule chúng ta khai báo các tham số sau đây:

  • declarations: tên lớp view thuộc về module này
  • exports: danh sách tên các module hoặc component có thể sử dụng module này
  • imports: tên các module sẽ được dùng từ module này
  • providers: tên các service sẽ được dùng từ module này, chúng ta sẽ tìm hiểu về service sau
  • bootstrap: tên lớp view dành cho root module, chỉ có root module mới thiết lập tham số này Đây là một đoạn code module trong file có tên app.module.ts đơn giản như sau:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
    imports:      [ BrowserModule ],
    providers:    [ Logger ],
    declarations: [ AppComponent ],
    exports:      [ AppComponent ],
    bootstrap:    [ AppComponent ]
})
export class AppModule { }

Để gọi module trên thì chúng ta code như sau:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
 
platformBrowserDynamic().bootstrapModule(AppModule);

Template là một đoạn code HTML để component dựa vào đó mà hiển thị trên màn hình. Ví dụ:

<h2>Hero List</h2>
<p><i>Pick a hero from the list</i></p>
<ul>
    <li *ngFor="let hero of heroes" (click)="selectHero(hero)">
        {{hero.name}}
    </li>
</ul>
<hero-detail *ngIf="selectedHero" [hero]="selectedHero"></hero-detail>

Ngoài các thẻ HTML thông thường như <h2>, <p> thì còn có những thẻ và thuộc tính đặc biệt như *ngFor, {{hero.name}}, (click), [hero] và <hero-detail>, đây là cú pháp template của Angular.

Metadata (siêu dữ liệu) là những thông tin giúp Angular xử lý các lớp.

Trong đoạn code ví dụ về Component ở trên, đó chỉ là một lớp bình thường viết bằng TypeScript, không có sự xuất hiện của Angular trong này. Muốn Angular hiểu được đó là một lớp dành cho Angular thì chúng ta phải khai báo metadata. Ví dụ:

@Component({
    moduleId: module.id,
    selector: 'hero-list',
    templateUrl: 'hero-list.component.html',
    providers: [ HeroService ]
})
export class HeroListComponent implements OnInit {
    /* . . . */
}

Trong đó @Component là từ khóa bắt đầu định nghĩa metadata, phần định nghĩa lớp ngay sau phần metadata này là lớp component của metadata trên. Bên trong chúng ta khai báo một số thông tin cho Angular như moduleId, selector, templateUrl, providers. Chúng ta sẽ tìm hiểu về chúng sau.

Data Binding tức là lấy dữ liệu từ model/controller đổ vào view. Trong đoạn code ví dụ về template trên có những dòng data binding như sau:

<li>{{hero.name}}</li>
<hero-detail [hero]="selectedHero"></hero-detail>
<li (click)="selectHero(hero)"></li>

Data binding trong Angular là 2 chiều, tức là chúng ta có thể nhập dữ liệu từ view vào model/controller.

<input [(ngModel)]="hero.name">

Directive (chỉ thị) là một lớp và có phần khai báo metadata là @Directive. Thường thì directive sẽ nằm trong một element – hay thẻ của HTML giống như một thuộc tính bình thường.

Có 2 loại directive là structuralattribute.

Các structural directive có chức năng gán dữ liệu theo một quy tắc nào đó.

<li *ngFor="let cus of customer"></li>
<customer *ngIf="selectedCustomer"></customer>

Trong đoạn code trên thì ngForngIf là các structural directive.

Các attribute directive có chức năng hiển thị dữ liệu một cách trực tiếp.

<input [(ngModel)]="hero.name">

Trong đoạn code trên thì ngModel là một attribute directive.

Service là các lớp có khả năng thực hiện một số chức năng thường dùng, nói đơn giản thì chúng giống như thư viện vậy. Một số service phổ biến là: logging service, data service, message bus, tax calculator, application configuration. Ví dụ lớp Logger cho phép chúng ta in các đoạn code báo lỗi, cảnh báo…v.v:

export class Logger {
    log(msg: any) { console.log(msg); }
    error(msg: any) { console.error(msg); }
    warn(msg: any) { console.warn(msg); }
}

Dependency là các lớp/module/service được dùng thêm, Dependency injection là khả năng cho phép tạo các đối tượng lớp có đầy đủ các lớp/module/service được dùng thêm đó. Chẳng hạn như chúng ta có phương thức constructor() như sau:

constructor(private service: HeroService) { }

Tham số private service: HeroService có nghĩa là lớp này cần dùng một service có tên HeroService. Angular có riêng một vùng bộ nhớ để lưu trữ các dependency đã được gọi, khi một module/component nào cần dùng service nào, Angular sẽ tìm trong vùng bộ nhớ đó xem có không, nếu không có thì Angular sẽ tạo một đối tượng của dependency đó và đưa vào bộ nhớ rồi trả về cho lớp đã gọi.

Khi chúng ta xây dựng root module thì chúng ta phải khai báo các dependency trong tham số providers, có như thế Angular mới có thể tìm được.

providers: [
    BackendService,
    HeroService,
    Logger
],

Hoặc khai báo ở phần @Component:

@Component({
    moduleId: module.id,
    selector: 'hero-list',
    templateUrl: 'hero-list.component.html',
    providers: [ HeroService ]
})

-Structural directives: cú pháp thay đổi đó là ng-repeat được thay thế bằng *ngFor. Angular 1.x structural directives

<ul>
   <li ng-repeat="technology in technologies">
     {{technology.name}}
   </li>
</ul>
<div ng-if="technologies.length">
   <h3>You have {{technologies.length}} technologies.</h3>
</div>

Angular 2.x structural directives

<ul>
  <li *ngFor="let technology of technologies">
    {{technology.name}}
  </li>
</ul>
<div *ngIf="technologies.length">
  <h3>You have {{technologies.length}} technologies.</h3>
</div>

-Angular 2, các biến local đều có sửa dụng tiền tố là ký tự (#) trong vòng lặp *ngFor. -Angular 2 sử dụng cú pháp camelCase. Ví dụ, ng-class bây giờ là ngClass và ng-model bây giờ là ngModel. ...

Trên đây là một tí kiến thức về kiến trúc về Angular2 mà mình đã tìm hiểu được, nếu muốn rõ hơn về kiến trúc bạn có thể tìm hiểu thêm tại:

  • https://www.tutorialspoint.com/angular2/
  • https://www.concretepage.com/angular-2/angular-2-custom-structural-directive-example
  • https://github.com/smithad15/angular2-folder-structure-example
0