Routing in Angular 2
Bài đăng này đã không được cập nhật trong 7 năm
Trong quá trình phát triển web, Routing có nghĩa là việc chia ứng dụng thành các phần khác nhau thường dựa theo những rules nhất định dựa vào url hiện tại. Ví dụ: nếu schungs ta truy cập vào đường dẫn "/" của website, chugns ta có thể truy cập tới home pages, hoặc "/about" chúng ta sẽ render ra trang "about page", v.v...
Why Do We Need Routing?
Việc định nghĩa ra routes là rất cần thiết và hữu dụng, về cơ bản chúng ta sẽ:
- Phân tách các khu vực khác nhau của app
- Duy trì trạng thái trong ứng dụng
- Bảo vệ các khu vực của ứng dụng theo những quy tắc nhất định
How client-side routing works
Có lẽ bạn đã từng viết server-side routing. Về nguyên tắc chung với server-side routing, http request nhảy đến và server sẽ render ra 1 controller khác, điều này phụ thuộc vào incoming URL
Ví dụ với Express.js
:
var express = require('express');
var router = express.Router();
// define the about route
router.get('/about', function(req, res) {
res.send('About us');
});
Hoặc với Ruby
:
# routes.rb
get '/about', to: 'pages#about'
# PagesController.rb
class PagesController < ActionController::Base
def about
render
end
end
Mẫu này thay đổi theo từng Framework, nhưng trong cả hai trường hợp này, bạn có một máy chủ chấp nhận một yêu cầu và các tuyến đến một bộ điều khiển và bộ điều khiển chạy một hành động cụ thể, tùy thuộc vào đường dẫn và thông số. Định tuyến phía máy khách là rất giống nhau trong khái niệm nhưng khác nhau trong thực hiện. Với phía client định tuyến không nhất thiết phải thực hiện yêu cầu đến máy chủ trên mọi thay đổi URL. Với Angular app, chúng ta gọi họ là "Ứng dụng Trang Đơn" (SPA) bởi vì máy chủ của chúng tôi chỉ cho chúng tôi một trang và đó là JavaScript của chúng tôi để hiển thị các trang khác nhau. Vậy làm cách nào để chúng tôi có các tuyến đường khác nhau trong mã JavaScript của chúng tôi?
The beginning: using anchor tags
<!-- ... lots of page content here ... -->
<a name="about"><h1>About</h1></a>
Khi chúng ta truy cập tới URL http://something/#about
, browser sẽ nhảy thẳng đến thẻ H1 đã được định nghĩa ở trên
Ví dụ, về lộ trình cho một SPA sẽ là một cái gì đó như http://something/#/about
. Đây là những gì được gọi là định tuyến dựa trên băm.
Điều gọn gàng về thủ thuật này là nó trông giống như một URL "normal" vì chúng ta đang bắt đầu anchor của chúng ta với một dấu gạch chéo (/about).
Writing our first routes
Trong Angular chúng ta configure routes bằng việc ánh xạ tới các component và handle chúng Chúng ta cùng đi vào 1 ứng dụng nho nhỏ với 3 routes chính:
- Trang chủ, sử dụng đường dẫn
/#/home
- Trang about, sử dụng đường dẫn
/#/about
- Trang contact, sử dụng đường dẫn
/#/contact
Khi user truy cập tới root path (/#/), chúng ta sẽ chuyển tiếp về home path
Components of Angular 2 routing
Có 3 thành phần chính mà chúng ta cần cấu hình routing trong Angular:
- Routes mô tả toàn bộ routes của ứng dụng sẽ suppport
- RouterOutlet là thành phần 'placehodler' mà angular sẽ đặt vào nội dung của mỗi routes
- RouterLink là một thành phần sẽ chỉ định đường dẫn tới routes Chúng ta sẽ cùng nhau xem xét rõ hơn.
Import
Để sử dụng router trong Angular, chúng ta phải import một số thành phần trong gói @angular/router
code/routes/basic/app/ts/app.ts
import {
RouterModule,
Routes
} from '@angular/router';
Bây giờ chúng ta đã có thể định nghĩa router trong ứng dụng của chúng ta
Routes
code/routes/basic/app/ts/app.ts
const routes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
{ path: 'contactus', redirectTo: 'contact' },
];
Lưu ý một vài điều về các routes
path
chỉ định URL mà tuyến đường này sẽ xử lýcomponent
là những gì ràng buộc một đường dẫn tuyến đường cho một thành phần sẽ xử lý các tuyến đườngredirectTo
1 tùy trịn được sử dụng để redirect tới 1 route đã tồn tại trong hệ thống
Redirections
Khi chúng ta sử dụng redirectTo
trên một định nghĩa tuyến đường, nó sẽ cho router thấy rằng khi chúng ta ghé thăm con đường của tuyến đường, chúng ta muốn chuyển hướng trình duyệt sang một tuyến khác.
Trong ví dụ mẫu ở trên của chúng tôi, nếu chúng ta truy cập đường dẫn gốc tại http://localhost:8080/#/
, chúng tôi sẽ được chuyển hướng đến route home
.
Một ví dụ khác là tuyến liên lạc:
{ path: 'contactus', redirectTo: 'contact' },
Installing our Routes
Để sử dụng routes trong ứng dụng của chings ta, chúng ta cần làm 2 việc đối với NgModule"
- import
RoutesModule
- cài đặt routes sử dụng
RouterModule.forRoot(routes)
trong import củaNgModule
Dưới đây là config trongNgModule
:code/routes/basic/app/ts/app.ts
const routes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
{ path: 'contactus', redirectTo: 'contact' },
];
@NgModule({
declarations: [
RoutesDemoApp,
HomeComponent,
AboutComponent,
ContactComponent
],
imports: [
BrowserModule,
RouterModule.forRoot(routes) // <-- routes
],
bootstrap: [ RoutesDemoApp ],
providers: [
{ provide: LocationStrategy, useClass: HashLocationStrategy }
]
})
class RoutesDemoAppModule {}
platformBrowserDynamic().bootstrapModule(RoutesDemoAppModule)
.catch((err: any) => console.error(err)
);
RouterOutlet using <router-outlet>
Khi thay đổi các routes, chúng tôi muốn giữ nguyên mẫu "layout" bên ngoài của và chỉ thay thế "inner section" của trang bằng route's component.
Để mô tả Angular, muốn hiển thị nội dung cho mỗi tuyến, ta sử dụng chỉ thị RouterOutlet.
Thành phần của chúng ta @Component có một template xác định một số cấu trúc div, một phần cho Navigation và một chỉ thị được gọi là router-outlet.
Phần tử router-outlet cho biết nơi mà nội dung của mỗi thành phần tuyến đường sẽ được hiển thị.
Dưới đây là component và template cho trình bao bọc navigation wrapper của ứng dụng:
code/routes/basic/app/ts/app.ts
@Component({
selector: 'router-app',
template: `
<div>
<nav>
<a>Navigation:</a>
<ul>
<li><a [routerLink]="['home']">Home</a></li>
<li><a [routerLink]="['about']">About</a></li>
<li><a [routerLink]="['contact']">Contact us</a></li>
</ul>
</nav>
<router-outlet></router-outlet>
</div>
`
})
class RoutesDemoApp {
}
Nếu chúng ta nhìn vào nội dung của template ở trên, bạn sẽ chú ý đến phần tử router-outlet bên dưới navigation menu. Khi chúng ta truy cập tới trang /home, đó là nơi mà mẫu HomeComponent sẽ được hiển thị. Điều tương tự cũng xảy ra đối với các thành phần khác.
RouterLink using [routerLink]
Bây giờ chúng ta biết nơi các tuyến đường sẽ được hiển thị, làm thế nào để chúng ta nói với Angular 2 để điều hướng đến một tuyến đường nhất định? Chúng tôi có thể thử liên kết tới các tuyến đường trực tiếp sử dụng HTML thuần túy:
<a href="/#/home">Home</a>
Nhưng nếu thực hiện việc này, chúng tôi sẽ nhận thấy rằng việc nhấp vào liên kết sẽ kích hoạt tải lại trang và chắc chắn đó không phải là điều chúng tôi muốn khi lập trình các ứng dụng một trang.
Để giải quyết vấn đề này, Angular 2 cung cấp một giải pháp có thể được sử dụng để liên kết đến các tuyến không tải trang: chỉ thị RouterLink.
Chỉ thị này cho phép bạn viết các liên kết sử dụng một cú pháp đặc biệt:
code/routes/basic/app/ts/app.ts
<a>Navigation:</a>
<ul>
<li><a [routerLink]="['home']">Home</a></li>
<li><a [routerLink]="['about']">About</a></li>
<li><a [routerLink]="['contact']">Contact us</a></li>
</ul>
Chúng ta có thể nhìn thấy ở phía bên trái [routerLink]
mà áp dụng các chỉ thị cho các yếu tố hiện tại (trong trường hợp của chúng tôi một thẻ).
Bây giờ, ở phía bên tay phải chúng ta có một mảng với đường dẫn tuyến như là phần tử đầu tiên, chẳng hạn như "['home']" hoặc "['about"] "sẽ chỉ ra đường để điều hướng đến khi chúng ta nhấp vào phần tử .
Có vẻ hơi kỳ quặc rằng giá trị của routerLink là một chuỗi với một mảng chứa một chuỗi (ví dụ "['home']"). Điều này là do có nhiều thứ bạn có thể cung cấp khi liên kết đến tuyến đường nhưng chúng tôi sẽ xem xét chi tiết hơn khi chúng ta nói về các routes con và các route tham số.
Hiện tại, chúng ta chỉ sử dụng các tên đường từ root app component.
Summary
Trên đây là một số khái niệm cơ bản về Routing trong Angular 2. Ở bài viết tiếp theo tôi sẽ trình bày về Routing strategies, Route Parameters,...
Tài liệu tham khảo ng-book 2, Felipe Coury, Ari Lerner, Nate Murray, & Carlos Taborda
All rights reserved