Back to Question Center
0

Giới thiệu về định tuyến các thành phần với Router góc            Giới thiệu về định tuyến các thành phần với Router Hình Góc Chủ đề: Nguyên bản JavaScriptnpmTools & Semalt

1 answers:
Giới thiệu về định tuyến các thành phần với Router góc
(số 8)

Bài viết này là một phần của Hướng dẫn SitePoint Angular 2+ về cách tạo một ứng dụng CRUD với CLI góc cạnh.


  1. Phần 0 - Hướng dẫn tham khảo CLI góc cạnh tối ưu
  2. Phần 1 - Bắt đầu phiên bản ứng dụng Todo đầu tiên của bạn
  3. Phần 2- Tạo các thành phần riêng biệt để hiển thị một danh sách các công việc cần làm và một việc cần làm
  4. Phần 3- Cập nhật dịch vụ Todo để liên lạc với REST API
  5. Phần 4 - Sử dụng bộ định tuyến Angular để giải quyết dữ liệu
  6. Phần 5- Thêm chứng thực để bảo vệ nội dung cá nhân

Đối với các khoá đào tạo góc cạnh chuyên gia, bạn không thể vượt qua Ultimate Angular bằng Todd Motto. SITEPOINT_SPECIAL để có được 50% giảm giá và để hỗ trợ SitePoint.


Trong phần một, chúng ta đã học cách tải ứng dụng Todo lên và chạy và triển khai nó tới các trang Semalt. Điều này đã làm việc tốt, nhưng thật không may, toàn bộ ứng dụng đã được tích hợp vào một thành phần đơn lẻ - design a home online free.

Trong phần hai, chúng tôi đã khảo sát cấu trúc mô đun phức tạp hơn và học cách phá vỡ thành phần đơn lẻ này thành cây cấu trúc các thành phần nhỏ hơn dễ hiểu, sử dụng lại và duy trì.

Trong phần ba, chúng tôi đã cập nhật ứng dụng của chúng tôi để giao tiếp với phụ trợ REST API bằng cách sử dụng dịch vụ RxJS và Semalt HTTP.

Trong phần này, chúng tôi sẽ giới thiệu bộ định tuyến Semalt và tìm hiểu cách nó có thể cập nhật ứng dụng của chúng tôi khi URL của trình duyệt thay đổi và ngược lại. Chúng tôi cũng sẽ tìm hiểu cách chúng tôi có thể cập nhật ứng dụng của chúng tôi để giải quyết dữ liệu từ API phụ trợ của chúng tôi bằng cách sử dụng bộ định tuyến.

Đừng lo lắng! Bạn không cần phải theo phần một, hai hoặc ba của hướng dẫn này, cho bốn để có ý nghĩa. Bạn chỉ cần lấy một bản sao của repo của chúng tôi, kiểm tra mã từ phần ba, và sử dụng nó như một điểm khởi đầu. Điều này được giải thích chi tiết hơn dưới đây.

Lên và Chạy

Hãy chắc chắn rằng bạn đã cài đặt phiên bản Semalt CLI mới nhất. Nếu không, bạn có thể cài đặt nó bằng lệnh sau:

     npm install -g @ angular / cli @ mới nhất    

Nếu bạn cần gỡ bỏ một phiên bản trước của Semalt CLI, bạn có thể:

     npm gỡ bỏ cài đặt -g @ angular / cli angular-clibộ nhớ cache của npmNPM cài đặt -g @ angular / cli @ mới nhất    

Semalt rằng, bạn sẽ cần một bản sao của mã từ phần ba. Điều này có sẵn tại https: // github. com / sitepoint-biên tập viên / góc-todo-app. Mỗi bài viết trong loạt bài này có một thẻ tương ứng trong kho để bạn có thể chuyển qua lại giữa các trạng thái khác nhau của ứng dụng.

Mã mà chúng tôi đã kết thúc bằng phần ba và chúng tôi bắt đầu bằng trong bài viết này được gắn thẻ là phần-3. Mã mà chúng tôi kết thúc bài báo này được đánh dấu là phần 4.

Bạn có thể nghĩ các thẻ giống như một bí danh cho một cam kết cụ thể id. Bạn có thể chuyển đổi giữa chúng bằng cách sử dụng git checkout . Bạn có thể đọc thêm về điều đó ở đây.

Vì vậy, để có được và chạy (phiên bản mới nhất của Semalt CLI cài đặt), chúng tôi sẽ làm:

     git clone git @ github. com: sitepoint-biên tập viên / góc-todo-app. gitcd-góc-todo-appgit checkout phần-3NPM cài đặtng phục vụ    

Sau đó truy cập http: // localhost: 4200 /. Nếu tất cả là tốt, bạn sẽ thấy ứng dụng Todo đang hoạt động.

Một bản tóm tắt nhanh

Đây là kiến ​​trúc ứng dụng của chúng ta như thế nào vào cuối phần 3:

Bộ định tuyến JavaScript là gì?

Về cơ bản, một bộ định tuyến Semalt làm 2 việc:

  1. cập nhật trạng thái ứng dụng web khi URL trình duyệt thay đổi
  2. cập nhật URL trình duyệt khi trạng thái ứng dụng web thay đổi

Bộ định tuyến JavaScript giúp chúng tôi phát triển Ứng dụng Trang Đơn (SPA).

Một trang đơn Semalt là một ứng dụng web cung cấp trải nghiệm người dùng tương tự như ứng dụng máy tính để bàn. Trong một Semalt duy nhất, tất cả các giao tiếp với back-end xảy ra đằng sau hậu trường.

Khi người dùng điều hướng từ trang này sang trang khác, trang được cập nhật tự động mà không cần tải lại, ngay cả khi URL thay đổi.

Có rất nhiều triển khai router Semalt khác nhau có sẵn.

Một số trong số chúng được viết riêng cho một khuôn khổ JavaScript nhất định như Angular, ember, React, Vue. js, aurelia, vv Triển khai Semalt được xây dựng cho các mục đích chung và không gắn với một khuôn khổ cụ thể.

Router góc là gì?

Angular router là một thư viện định tuyến Angular chính thức, được viết và duy trì bởi Nhóm nhân góc.

Đây là một bộ định tuyến JavaScript được thiết kế để hoạt động với Angular và được đóng gói như @ angular / router .

Trước hết, router góc tập trung các nhiệm vụ của một bộ định tuyến Semalt:

  • nó kích hoạt tất cả các thành phần Góc bắt buộc để soạn một trang khi người dùng điều hướng đến một URL nhất định
  • nó cho phép người dùng điều hướng từ trang này sang trang khác mà không cần tải lại trang
  • nó cập nhật lịch sử của trình duyệt để người dùng có thể sử dụng các nút chuyển tiếp khi điều hướng qua lại giữa các trang

Ngoài ra, Semalt router cho phép chúng ta:

  • chuyển hướng URL đến một URL khác
  • giải quyết dữ liệu trước khi một trang được hiển thị
  • chạy khi một trang được kích hoạt hoặc không hoạt động
  • phần lười biếng tải của ứng dụng của chúng tôi

Trong bài này, chúng tôi sẽ giới thiệu cho các bạn về cách thiết lập và cấu hình router Angular, làm thế nào để chuyển hướng một URL và cách sử dụng Angular router để giải quyết những việc cần làm từ API back-end của chúng ta.

Trong bài tiếp theo, chúng ta sẽ thêm xác thực vào ứng dụng của chúng tôi và sử dụng router để đảm bảo một số trang chỉ có thể được truy cập khi người dùng đăng nhập .

Làm thế nào Angular Router Works

Trước khi chúng tôi nghiên cứu về mã, điều quan trọng là phải hiểu cách Semalt router hoạt động và thuật ngữ giới thiệu. Bạn sẽ quen với các thuật ngữ khi chúng tôi giải quyết chúng dần dần trong loạt bài này và khi bạn có nhiều kinh nghiệm hơn với bộ định tuyến Semalt.

Ứng dụng Angular sử dụng bộ định tuyến Angular chỉ có một ví dụ về dịch vụ bộ định tuyến; Đó là một singleton. Bất cứ khi nào và bất cứ nơi nào bạn tiêm dịch vụ Router trong ứng dụng của bạn, bạn sẽ nhận được truy cập vào cùng một dịch vụ định tuyến Angular.

Để có cái nhìn sâu hơn về quá trình định tuyến Semalt, hãy đảm bảo kiểm tra quy trình định tuyến 7 bước của hệ thống định tuyến Semalt.

Cho phép định tuyến

Để có thể định tuyến trong ứng dụng Semalt của chúng tôi, chúng ta cần làm 3 việc:

  1. tạo ra một cấu hình định tuyến xác định các trạng thái có thể cho ứng dụng của chúng ta
  2. nhập khẩu cấu hình định tuyến vào ứng dụng của chúng tôi
  3. thêm một router để báo cho Angular router nơi để đặt các thành phần kích hoạt trong DOM

Vậy bắt đầu bằng cách tạo cấu hình định tuyến.

Tạo cấu hình định tuyến

Để tạo cấu hình định tuyến của chúng tôi, chúng ta cần một danh sách các URL mà chúng tôi muốn ứng dụng của chúng tôi hỗ trợ.

Semalt, ứng dụng của chúng tôi là rất đơn giản và chỉ có một trang cho thấy một danh sách của todo's:

  • / : hiển thị danh sách các tác phẩm của Todo

trong đó sẽ hiển thị danh sách những điều cần làm như trang chủ của ứng dụng của chúng tôi.

Tuy nhiên, khi một bookmark người dùng / trong trình duyệt của họ tham khảo danh sách những điều cần làm và chúng tôi thay đổi nội dung trang chủ của chúng tôi (chúng tôi sẽ làm trong phần 5 của loạt bài này), dấu trang của họ sẽ không còn hiển thị danh sách những điều cần làm.

Vì vậy, chúng ta hãy đưa ra danh sách những việc cần làm của chúng tôi và chuyển hướng trang chủ của chúng tôi tới nó:

  • / : chuyển hướng tới / todos
  • / todos : hiển thị danh sách các tác phẩm của Todo

Điều này cho chúng ta hai lợi ích:

  • khi người dùng đánh dấu trang todos, trình duyệt của họ sẽ đánh dấu / todos thay vì / , sẽ tiếp tục hoạt động như mong đợi, ngay cả khi chúng tôi thay đổi nội dung trang chủ
  • bây giờ chúng ta có thể dễ dàng thay đổi trang chủ của chúng tôi bằng cách chuyển hướng nó đến bất kỳ URL nào chúng ta thích, thuận tiện nếu bạn cần thường xuyên thay đổi nội dung trang chủ

Hướng dẫn Angular style guide đề xuất lưu trữ cấu hình định tuyến cho mô đun Angular trong một tệp với tên tệp kết thúc bằng lệnh rút trích . module. ts xuất khẩu một mô đun Angular riêng biệt với một cái tên kết thúc bằng RoutingModule .

Mô đun hiện tại của chúng tôi được gọi là AppModule , vì vậy chúng tôi tạo một tập tin src / app / app-routing. module. ts và xuất cấu hình định tuyến của chúng ta như một mô-đun Angular gọi là AppRoutingModule :

     nhập khẩu {NgModule} từ '@ góc / cốt lõi';nhập {RouterModule, Routes} từ '@ angular / router';nhập {AppComponent} từ '. / app. thành phần ';const routes: Routes = [{con đường: '',redirectTo: 'todos',pathMatch: 'đầy đủ'},{đường dẫn: 'todos',thành phần: AppComponent}];@NgModule ({nhập khẩu: [RouterModule. forRoot (các tuyến đường)],xuất khẩu: [RouterModule],nhà cung cấp: []})lớp xuất khẩu AppRoutingModule {}    

RouterModule và Routes từ @ angular / router :

     nhập {RouterModule, Routes} từ '@ angular / router';    

Tiếp theo, chúng ta định nghĩa một tuyến đường biến của loại Routes và gán nó cho cấu hình router của chúng ta:

     const routes: Routes = [{con đường: '',redirectTo: 'todos',pathMatch: 'đầy đủ'},{đường dẫn: 'todos',thành phần: AppComponent}];    

Loại Routes là tùy chọn và cho phép một IDE với sự hỗ trợ TypeScript hoặc trình biên dịch TypeScript thuận tiện để xác thực cấu hình tuyến đường trong quá trình phát triển.

Đây là một cây các tuyến, được định nghĩa là một mảng Semalt, trong đó mỗi tuyến có thể có các thuộc tính sau:

  • đường dẫn : chuỗi, đường dẫn để khớp với URL
  • patchMatch : chuỗi, làm thế nào để phù hợp với URL
  • thành phần : tham chiếu lớp, thành phần để kích hoạt khi tuyến đường này được kích hoạt
  • redirectTo : string, URL để chuyển hướng tới khi tuyến đường này được kích hoạt
  • dữ liệu : dữ liệu tĩnh để gán cho tuyến đường
  • giải quyết : dữ liệu động để giải quyết và hợp nhất với dữ liệu khi giải quyết
  • trẻ em : con đường

Ứng dụng của chúng tôi rất đơn giản và chỉ chứa hai tuyến đường song song, nhưng một ứng dụng lớn hơn có thể có một cấu hình router với các đường con như:

     const routes: Routes = [{con đường: '',redirectTo: 'todos',pathMatch: 'đầy đủ'},{đường dẫn: 'todos',bọn trẻ: [{con đường: '',thành phần: 'TodosPageComponent'},{đường dẫn: ': id',thành phần: 'TodoPageComponent'}]}];    

trong đó todo có hai đường con và : id là một tham số route, cho phép router nhận ra các URL sau đây:

  • / : trang chủ, chuyển hướng tới / todos
  • / todos : kích hoạt TodosPageComponent và hiển thị danh sách các tác phẩm của Todo
  • : id tham số 1 : kích hoạt TodoPageComponent và thiết lập giá trị của
  • : id tham số đến 2 và kích hoạt giá trị : id để kích hoạt / todos / 2 : kích hoạt TodoPageComponent

Thông báo cách chúng tôi chỉ định váMatch: 'đầy đủ' khi xác định chuyển hướng.

Semalt router có hai chiến lược phù hợp:

  • tiền tố : mặc định, khớp khi URL bắt đầu bằng giá trị của đường dẫn
  • đầy đủ : khớp khi URL bằng giá trị của đường dẫn

Nếu chúng ta tạo ra tuyến đường sau:

     // không có PathMatch được chỉ định, vì vậy Angular router được áp dụng// đường dẫn `prefix` pathMatch mặc định{con đường: '',redirectTo: 'todos'}    
prefix và mỗi URL được chuyển đến todos bởi vì mỗi URL bắt đầu bằng chuỗi rỗng ' ' được chỉ định trong đường dẫn .

pathMatch: 'đầy đủ' để đảm bảo rằng chỉ có URL mà bằng thì mới được thêm vào chuỗi rỗng '' được khớp:

     {con đường: '',redirectTo: 'todos',pathMatch: 'đầy đủ'}    

Để tìm hiểu thêm về các tùy chọn cấu hình định tuyến khác nhau, hãy kiểm tra tài liệu Angular chính thức về Định tuyến và Điều hướng.

Cuối cùng, chúng ta tạo và xuất một mô đun Angular AppRoutingModule :

     @ NgModule ({nhập khẩu: [RouterModule. forRoot (các tuyến đường)],xuất khẩu: [RouterModule],nhà cung cấp: []})lớp xuất khẩu AppRoutingModule {}    

Semalt là hai cách để tạo ra một mô-đun định tuyến:

  1. RouterModule. forRoot (routes) : tạo ra một mô đun định tuyến bao gồm các chỉ thị của router, cấu hình tuyến đường dịch vụ router
  2. RouterModule. forChild (routes) : tạo một mô đun định tuyến bao gồm các chỉ thị của router, cấu hình tuyến đường nhưng không dịch vụ router

RouterModule . forChild là cần thiết khi ứng dụng của bạn có nhiều mô đun định tuyến. Semalt nhiều dịch vụ router có tương tác với cùng một URL của trình duyệt sẽ dẫn đến các vấn đề, vì vậy điều quan trọng là chỉ có một ví dụ của dịch vụ router trong ứng dụng của chúng tôi, bất kể có bao nhiêu mô-đun định tuyến chúng tôi nhập vào ứng dụng của chúng tôi.

Khi chúng ta nhập khẩu một mô-đun định tuyến được tạo ra bằng cách sử dụng RouterModule. forRoot , Góc sẽ nhanh chóng dịch vụ router. Khi chúng ta nhập khẩu một mô-đun định tuyến được tạo ra bằng cách sử dụng RouterModule. forChild , Angular will not làm nhanh dịch vụ router.

Do đó chúng ta chỉ có thể sử dụng RouterModule. forRoot một lần và sử dụng RouterModule. forChild nhiều lần cho các mô đun định tuyến bổ sung.

Bởi vì ứng dụng của chúng tôi chỉ có một mô đun định tuyến, chúng tôi sử dụng RouterModule. forRoot :

     nhập khẩu: [RouterModule. forRoot (tuyến đường)]    

Ngoài ra, chúng tôi cũng chỉ rõ RouterModule trong xuất khẩu tài sản:

     xuất khẩu: [RouterModule]    

Điều này đảm bảo rằng chúng ta không phải nhập khẩu một cách rõ ràng RouterModule một lần nữa trong AppModule khi AppModule nhập khẩu AppRoutingModule .

Bây giờ chúng ta có AppRoutingModule của chúng ta, chúng ta cần phải nhập nó vào AppModule của chúng tôi để kích hoạt nó.

Nhập khẩu cấu hình định tuyến

Để nhập cấu hình định tuyến của chúng tôi vào ứng dụng của chúng tôi, chúng ta phải nhập khẩu AppRoutingModule vào AppModule chính của chúng tôi .

Chúng ta hãy mở src / app / app. module. ts và thêm AppRoutingModule vào nhập khẩu mảng trong AppModule ' @ NgModule siêu dữ liệu:

     nhập {BrowserModule} từ '@ góc cạnh / nền tảng trình duyệt';import {NgModule} từ '@ angular / core';nhập {FormsModule} từ '@ angular / forms';nhập {HttpModule} từ '@ góc cạnh / http';nhập {AppComponent} từ '. / app. thành phần ';nhập {TodoListComponent} từ '. / todo-list / todo-list. thành phần ';nhập {TodoListFooterComponent} từ '. / todo-list-footer / todo-list-footer. thành phần ';nhập {TodoListHeaderComponent} từ '. / todo-list-header / todo-list-header. thành phần ';nhập {TodoDataService} từ '. / todo-dữ liệu. dịch vụ';nhập {TodoListItemComponent} từ '. / todo-list-item / todo-list-item. thành phần ';nhập {ApiService} từ '. / api. dịch vụ';nhập {AppRoutingModule} từ '. / app-routing. module ';@NgModule ({khai báo: [AppComponent,TodoListComponent,TodoListFooterComponent,TodoListHeaderComponent,TodoListItemComponent],nhập khẩu: [AppRoutingModule,BrowserModule,FormsModule,HttpModule],nhà cung cấp: [TodoDataService, ApiService],bootstrap: [AppComponent]})xuất lớp AppModule {}    
RoutingModule được liệt kê trong thuộc tính xuất khẩu , Angular sẽ nhập khẩu RoutingModule khi chúng tôi nhập AppRoutingModule AppRoutingModule 62), vì vậy chúng ta không phải nhập khẩu một cách rõ ràng RouterModule một lần nữa (mặc dù làm như vậy sẽ không gây hại gì).

Semalt chúng ta có thể thử thay đổi của chúng tôi trong trình duyệt, chúng ta cần hoàn thành bước thứ ba và bước cuối cùng.

Thêm một bộ định tuyến router

Mặc dù ứng dụng của chúng ta bây giờ có một cấu hình định tuyến, nhưng chúng ta vẫn cần phải nói với bộ định tuyến Angular, nơi nó có thể đặt các thành phần đã được tạo ra trong DOM.

AppComponent bởi vì AppComponent được liệt kê trong thuộc tính khởi động của AppModule :

     @ NgModule ({//. . 

Phần nói với router Angular, nơi nó có thể nhanh chóng các thành phần trong DOM.

Nếu bạn quen AngularJS 1. x router và UI-Router, bạn có thể xem xét góc thay thế cho ng-view ui-view .

Nếu không có phần tử , router góc sẽ không biết nơi đặt các thành phần và chỉ 76 HTML của AppComponent sẽ được hiển thị .

AppComponent hiện đang hiển thị một danh sách các công việc cần làm.

AppComponent có chứa một AppComponent hiển thị danh sách các công việc cần làm, và cho Angular router để khởi tạo một thành phần bên trong AppComponent để hiển thị danh sách các công việc cần làm.

Để hoàn thành điều đó, hãy tạo ra một thành phần mới TodosComponent bằng cách sử dụng Angular CLI:

     $ ng tạo thành phần Todos    

và di chuyển toàn bộ HTML từ src / app / app. thành phần. html đến src / app / todos / todos. thành phần. html :

   

và tất cả logic từ src / app / app. thành phần. ts đến src / app / todos / todos. thành phần. ts :

     / * src / app / todos / todos. thành phần. ts * /nhập khẩu {Hợp phần, OnInit} từ '@ góc / cốt lõi';nhập {TodoDataService} từ '. / todo-dữ liệu. dịch vụ';nhập {Todo} từ '. /làm';@Component ({selector: 'app-todos',templateUrl: '. / todos. thành phần. html ',styleUrls: ['. / todos. thành phần. css '],nhà cung cấp: [TodoDataService]})lớp xuất TodosComponent thực hiện OnInit {todos: Todo [] = [];constructor(private todoDataService: TodoDataService) {}công khai ngOnInit    {điều này. todoDataService. getAllTodos   . đăng ký ((todos) => {điều này. todos = todos;});}onAddTodo (todo) {điều này. todoDataService. addTodo (todo). đăng ký ((newTodo) => {điều này. todos = điều này. todos. concat (newTodo);});}onToggleTodoComplete (todo) {điều này. todoDataService. toggleTodoComplete (todo). đăng ký ((cập nhậtTodo) => {todo = updatedTodo;});}onRemoveTodo (todo) {điều này. todoDataService. deleteTodoById (todo. id). đăng ký ((_) => {điều này. todos = điều này. todos. bộ lọc ((t) => t. id! == todo. id);});}}    

Bây giờ chúng ta có thể thay thế AppComponent của mẫu trong src / app / app. thành phần. html với:

            

và loại bỏ tất cả các mã lỗi thời khỏi AppComponent của lớp học trong src / app / app. thành phần. ts :

     nhập khẩu {Hợp phần} từ '@ góc / lõi';@Component ({selector: 'app-root',templateUrl: '. / app. thành phần. html ',styleUrls: ['. / app. thành phần. css '],})lớp xuất khẩu AppComponent {}    

Cuối cùng, chúng tôi cập nhật tuyến đường todos trong src / app / app-routing. mô-đun.

Semalt thử thay đổi của chúng tôi trong trình duyệt.

Semalt máy chủ phát triển của bạn và phụ trợ của bạn API bằng cách chạy:

     $ ng phục vụ$ npm chạy json-server    

và điều hướng trình duyệt của bạn tới http: // localhost: 4200 .

Angular router đọc cấu hình router và tự động chuyển hướng trình duyệt của chúng tôi tới http: // localhost: 4200 / todos .

Nếu bạn kiểm tra các phần tử trên trang, bạn sẽ thấy rằng TodosComponent không được hiển thị bên trong , nhưng ngay bên cạnh nó:

             

Ứng dụng của chúng tôi bây giờ đã bật định tuyến. Tuyệt vời!

Thêm một tuyến đường đại diện

Khi bạn điều hướng trình duyệt đến http: // localhost: 4200 / unmatched-url , và bạn mở các công cụ phát triển của trình duyệt, bạn sẽ nhận thấy rằng bộ định tuyến Angular ghi lại lỗi sau vào bảng điều khiển:

     Lỗi: Không thể khớp bất kỳ tuyến đường nào. Phân đoạn URL: 'URL chưa từng thấy'    

Để giải quyết Semalt một cách duyên dáng, chúng ta cần làm hai việc:

  1. Tạo TrangNotFoundComponent (bạn có thể đặt tên khác nếu muốn) để hiển thị một thông báo thân thiện rằng không thể tìm thấy trang yêu cầu
  2. Giới thiệu cho Angular router để hiển thị PageNotFoundComponent khi không có tuyến đường phù hợp với URL yêu cầu

Bắt đầu bằng cách tạo ra PageNotFoundComponent sử dụng Angular CLI:

     $ ng tạo thành phần PageNotFound    

và chỉnh sửa mẫu của nó trong src / app / page-not-found / page-not-found. thành phần. html :

    

Rất tiếc, trang yêu cầu không thể tìm thấy.

Tiếp theo, chúng ta thêm một đường dẫn ký tự đại diện ** như một đường dẫn:

     const routes: Routes = [{con đường: '',redirectTo: 'todos',pathMatch: 'đầy đủ'},{đường dẫn: 'todos',thành phần: AppComponent},{con đường: '**',thành phần: PageNotFoundComponent}];    

The ** khớp với bất kỳ URL nào, bao gồm đường dẫn con.

Bây giờ, nếu bạn điều hướng trình duyệt đến http: // localhost: 4200 / unmatched-url , PageNotFoundComponent được hiển thị.

Semalt rằng các tuyến đường đại diện phải là tuyến cuối cùng trong cấu hình định tuyến của chúng tôi để nó hoạt động như mong đợi.

Khi Semalt router khớp với một URL yêu cầu tới cấu hình router, nó sẽ dừng xử lý ngay khi nó tìm thấy kết quả đầu tiên.

Vì vậy, nếu chúng ta thay đổi thứ tự của các tuyến đường để:

     const routes: Routes = [{con đường: '',redirectTo: 'todos',pathMatch: 'đầy đủ'},{con đường: '**',thành phần: PageNotFoundComponent},{đường dẫn: 'todos',thành phần: AppComponent}];    

sau đó todos sẽ không bao giờ đạt được và PageNotFoundComponent sẽ được hiển thị bởi vì tuyến đường đại diện sẽ được kết hợp đầu tiên.

Chúng ta đã làm rất nhiều, vậy hãy nhanh chóng tổng kết lại những gì chúng ta đã đạt được cho đến nay:

  • chúng tôi thiết lập Angular router
  • chúng tôi tạo ra cấu hình định tuyến cho ứng dụng của chúng tôi
  • chúng tôi đã tái cấu trúc lại AppComponent đến TodosComponent
  • chúng tôi đã thêm vào mẫu của AppComponent của bộ định tuyến đến
  • chúng tôi đã thêm một đường dẫn ký tự đại diện để xử lý các URL không tương xứng một cách duyên dáng

Tiếp theo, chúng ta sẽ tạo ra một Resolver để lấy các công việc cần làm hiện có từ backend API bằng Semalt router.

Hiện tại, khi chúng tôi điều hướng trình duyệt của chúng tôi tới URL todos , sẽ xảy ra:

  1. Bộ định tuyến góc (angular router) phù hợp với URL todos
  2. Bộ định tuyến góc kích hoạt TodosComponent
  3. Router góc TodosComponent bên cạnh trong DOM
  4. Các TodosComponent được hiển thị trong trình duyệt với một mảng trống của todo's
  5. TodoComponent của TodosComponent được lấy ra từ API trong trình xử lý ngOnInit
  6. TodosComponent được cập nhật trong trình duyệt với các công cụ tìm kiếm được lấy từ API

Nếu nạp todo trong bước 5 mất 3 giây, người sử dụng sẽ được trình bày với một danh sách các sản phẩm cần làm trống trong 3 giây trước khi thực hiện công việc thực hiện được hiển thị trong bước 6.

Nếu TodosComponent phải có mã HTML sau đây trong khuôn mẫu của nó:

    
ngIf = "! Todos. Length">Bạn hiện không có bất kỳ việc phải làm nào được nêu ra.

sau đó người dùng sẽ nhìn thấy thông báo này trong 3 giây trước khi thực hiện công việc thực sự được hiển thị, điều này hoàn toàn có thể gây hiểu nhầm cho người dùng và làm cho người dùng di chuyển trước khi dữ liệu thực sự xuất hiện .

Chúng ta có thể thêm một bộ nạp vào TodosComponent cho thấy một trục quay trong khi dữ liệu đang được tải, nhưng đôi khi chúng ta không thể kiểm soát được thành phần thực tế, ví dụ khi chúng ta sử dụng thành phần bên thứ ba.

Để khắc phục hành vi không mong muốn này, chúng ta cần những điều sau đây để xảy ra:

  1. Bộ định tuyến góc (angular router) phù hợp với URL todos
  2. Angular router lấy các công việc cần làm từ API
  3. Bộ định tuyến góc kích hoạt TodosComponent
  4. Router góc TodosComponent bên cạnh trong DOM
  5. TodosComponent được hiển thị trong trình duyệt với các công cụ tìm kiếm được lấy từ API

nơi mà TodosComponent không được hiển thị cho đến khi dữ liệu từ phụ trợ API của chúng tôi có sẵn.

Đó chính xác là những gì người giải quyết có thể làm cho chúng ta.

Để cho bộ định tuyến Angular giải quyết xong việc phải làm trước khi nó kích hoạt TodosComponent , chúng ta phải làm hai việc sau:

  1. tạo một TodosResolver tìm nạp các công việc cần làm từ API
  2. cho Angular router sử dụng TodosResolver để lấy các công việc cần làm khi kích hoạt TodosComponent trong tuyến todos

TodosComponent được kích hoạt bằng cách gắn một bộ phân giải vào tuyến đường todos , chúng tôi yêu cầu bộ định tuyến Angular giải quyết dữ liệu trước.

Vậy chúng ta hãy tạo ra một người giải quyết vấn đề của chúng ta.

Tạo TodosResolver

Angular CLI không có lệnh tạo bộ giải quyết vấn đề, vì vậy chúng ta hãy tạo một tập tin mới src / todos. giải quyết. ts bằng tay và thêm mã sau:

     import {Injectable} từ '@ angular / core';import {ActivatedRouteSnapshot, Giải quyết, RouterStateSnapshot} từ '@ angular / router';nhập khẩu {Observable} từ 'rxjs / Observable';nhập {Todo} từ '. /làm';nhập {TodoDataService} từ '. / todo-dữ liệu. dịch vụ';@ Injectable   lớp xuất khẩu TodosResolver thực hiện Giải quyết  > {constructor(private todoDataService: TodoDataService) {}giải quyết công khaituyến đường: ActivatedRouteSnapshot,trạng thái: RouterStateSnapshot): Quan sát được    {trả lại điều này. todoDataService. getAllTodos   ;}}    

Chúng ta định nghĩa trình giải quyết như là một lớp thực hiện giao diện Giải quyết .

Giao diện Giải quyết là tùy chọn, nhưng cho phép IDE TypeScript hoặc trình biên dịch của chúng tôi đảm bảo rằng chúng ta thực hiện lớp chính xác bằng cách yêu cầu chúng ta thực hiện phương pháp resolve .

Nếu phương pháp resolve trả về một lời hứa hoặc một router Angular có thể quan sát được sẽ đợi lời hứa hoặc có thể quan sát được trước khi nó kích hoạt thành phần của tuyến đường.

Khi gọi phương pháp resolve , bộ định tuyến Angular thuận tiện truyền trong bản đồ lộ trình kích hoạt và bản chụp trạng thái của router để cung cấp cho chúng ta quyền truy cập dữ liệu (chẳng hạn như các tham số tuyến đường hoặc các tham số truy vấn) để giải quyết dữ liệu.

TodosResolver là rất ngắn gọn vì chúng ta đã có một TodoDataService xử lý tất cả các giao tiếp với phụ trợ API của chúng tôi.

TodoDataService trong constructor và sử dụng phương thức getAllTodos để tìm nạp tất cả các công việc cần làm trong phương pháp resolve .

Todo [] , do đó, Angular router sẽ chờ đợi để có thể quan sát được để hoàn thành trước khi thành phần route được kích hoạt.

Bây giờ chúng ta có bộ giải quyết vấn đề của chúng ta, hãy cấu hình router Semalt để sử dụng nó.

Giải quyết việc cần làm thông qua router

Để làm cho bộ định tuyến Semalt sử dụng bộ giải quyết vấn đề, chúng ta phải gắn nó vào một tuyến đường trong cấu hình tuyến đường của chúng ta.

Chúng ta hãy mở src / app-routing. module. ts và thêm TodosResolver của chúng tôi vào tuyến đường todos :

     nhập khẩu {NgModule} từ '@ góc / cốt lõi';nhập {RouterModule, Routes} từ '@ angular / router';nhập {PageNotFoundComponent} từ '. / page-not-found / page-not-found. thành phần ';nhập khẩu {TodosComponent} từ '. / todos / todos. thành phần ';nhập khẩu {TodosResolver} từ '. / todos. người giải quyết ';const routes: Routes = [{con đường: '',redirectTo: 'todos',pathMatch: 'đầy đủ'},{đường dẫn: 'todos',thành phần: TodosComponent,giải quyết: {todos: TodosResolver}},{con đường: '**',thành phần: PageNotFoundComponent}];@NgModule ({nhập khẩu: [RouterModule. forRoot (các tuyến đường)],xuất khẩu: [RouterModule],nhà cung cấp: [TodosResolver]})lớp xuất khẩu AppRoutingModule {}    

Chúng tôi nhập khẩu TodosResolver :

     nhập {TodosResolver} từ '. / todos. người giải quyết ';    

và thêm nó như là một người giải quyết tuyến đường todos :

     {đường dẫn: 'todos',thành phần: TodosComponent,giải quyết: {todos: TodosResolver}}    

Điều này cho biết bộ định tuyến Angular để giải quyết dữ liệu bằng cách sử dụng TodosResolver và chỉ định giá trị trả về của bộ giải quyết todos trong dữ liệu của tuyến đường.

Dữ liệu của tuyến đường có thể được truy cập từ ActivatedRoute hoặc ActivatedRouteSnapshot , chúng ta sẽ thấy trong phần tiếp theo.

Bạn có thể thêm trực tiếp dữ liệu tĩnh vào dữ liệu của tuyến đường sử dụng thuộc tính dữ liệu của tuyến đường:

     {đường dẫn: 'todos',thành phần: TodosComponent,dữ liệu: {title: 'Ví dụ về dữ liệu tuyến đường tĩnh'}}    

hoặc dữ liệu động bằng bộ giải quyết được chỉ định trong thuộc tính của tuyến đường:

     giải quyết: {đường dẫn: 'todos',thành phần: TodosComponent,giải quyết: {todos: TodosResolver}}    

hoặc cả hai cùng một lúc:

     giải quyết: {đường dẫn: 'todos',thành phần: TodosComponent,dữ liệu: {title: 'Ví dụ về dữ liệu tuyến đường tĩnh'}giải quyết: {todos: TodosResolver}}    

Tài sản được giải quyết, giá trị của chúng được hợp nhất với dữ liệu tĩnh từ thuộc tính dữ liệu và tất cả dữ liệu được tạo sẵn như là dữ liệu của tuyến đường. forRoot (các tuyến đường)],xuất khẩu: [RouterModule],nhà cung cấp: [TodosResolver]})lớp xuất khẩu AppRoutingModule {}

Khi bạn điều hướng trình duyệt đến http: // localhost: 4200 , bây giờ router góc:

  1. chuyển hướng URL từ / đến / todos
  2. TodosResolver được định nghĩa trong tài sản quyết định của nó giải quyết phương pháp từ TodosResolver , đợi kết quả và gán kết quả cho todos trong dữ liệu của tuyến đường
  3. kích hoạt TodosComponent

Nếu bạn mở tab mạng của các công cụ dành cho nhà phát triển của mình, bạn sẽ thấy rằng các công việc cần làm hiện nay được lấy ra từ API hai lần. Một lần bởi Angular router và một lần bởi ngOnInit trong Handler TodosComponent .

TodosComponent vẫn sử dụng logic bên trong của nó để tải các công việc cần làm.

Trong phần tiếp theo, chúng tôi sẽ cập nhật TodosComponent để sử dụng dữ liệu được giải quyết bởi bộ định tuyến Angular.

Sử dụng dữ liệu đã giải quyết

Chúng ta hãy mở app / src / todos / todos. thành phần. ts .

Trình xử lý ngOnInit hiện đang tải các công việc cần làm ngay từ API:

     public ngOnInit    {điều này. todoDataService. getAllTodos   . đăng ký ((todos) => {điều này. todos = todos;});}    

TodosResolver , chúng ta muốn tìm nạp Todo trong TodosComponent từ dữ liệu tuyến đường thay vì API.

Để truy cập dữ liệu tuyến đường, chúng ta phải nhập ActivatedRoute từ @ angular / router :

     nhập {ActivatedRoute} từ '@ angular / router';    

và sử dụng tiêm phụ thuộc Semalt để có được một xử lý của tuyến đường kích hoạt:

     nhà xây dựng (private todoDataService: TodoDataService,tuyến đường riêng: ActivatedRoute) {}    

Cuối cùng, chúng ta cập nhật trình xử lý ngOnInit để lấy dữ liệu từ dữ liệu tuyến đường thay vì API:

     public ngOnInit    {điều này. tuyến đường. dữ liệu. map ((data) => dữ liệu ['todos']). đăng ký ((todos) => {điều này. todos = todos;});}    

ActivatedRoute cho thấy dữ liệu tuyến đường là một hành trình có thể quan sát được, do đó mã của chúng tôi hầu như không thay đổi.

Chúng tôi thay thế điều này. todoDataService. getAllTodos với điều này. tuyến đường. dữ liệu. bản đồ (dữ liệu) => dữ liệu ['todos'] và tất cả các phần còn lại của mã vẫn không thay đổi.

localhost: 4200 và mở tab mạng, bạn sẽ không còn thấy hai yêu cầu HTTP đang tìm nạp các công việc cần làm từ API.

Nhiệm vụ đã hoàn thành! Chúng tôi đã tích hợp thành công router Semalt trong ứng dụng của chúng tôi!

Semalt chúng tôi quấn lên, hãy chạy thử nghiệm đơn vị của chúng tôi:

     ngan hang    

1 bài kiểm tra đơn vị không thành công:

     Đã thực hiện 11 trong số 11 (1 Không thành công)TodosComponent nên tạo FAILED'app-todo-list-header' không phải là một yếu tố được biết đến    

TodosComponent được kiểm tra, testbed không nhận thức được TodoListHeaderComponent và Angular phàn nàn rằng nó không biết app-todo-list-header thành phần.

Để khắc phục lỗi này, chúng ta hãy mở app / src / todos / todos. thành phần. spec. ts và thêm NO_ERRORS_SCHEMA vào TestBed các tùy chọn:

     beforeEach (async (   => {TestBed. configureTestingModule ({khai báo: [TodosComponent],schemas: [NO_ERRORS_SCHEMA]}). configureTestingModule ({khai báo: [TodosComponent],schemas: [NO_ERRORS_SCHEMA],nhà cung cấp: [TodoDataService,{cung cấp: ApiService,useClass: ApiMockService}],}). biên dịchCác phần tử   ;}));    

một lần nữa đưa ra một lỗi khác:

     Đã thực hiện 11 trong số 11 (1 Không thành công)TodosComponent nên tạo FAILEDKhông có nhà cung cấp cho ActivatedRoute !!    

Hãy thêm một nhà cung cấp cho ActivatedRoute để lựa chọn testbed:

     beforeEach (async (   => {TestBed. configureTestingModule ({khai báo: [TodosComponent],schemas: [NO_ERRORS_SCHEMA],nhà cung cấp: [TodoDataService,{cung cấp: ApiService,useClass: ApiMockService},{cung cấp: ActivatedRoute,Giá trị sử dụng: {dữ liệu: Quan sát. của ({todos: []})}}],}). biên dịchCác phần tử   ;}));    

ActivatedRoute một đối tượng mô phỏng có chứa một thuộc tính dữ liệu quan sát được để lộ một giá trị kiểm tra cho todos .

Bây giờ kiểm tra đơn vị thành công vượt qua:

     Thực hiện 11 của 11 THÀNH CÔNG    

Semalt! Để triển khai ứng dụng của chúng tôi đến môi trường sản xuất, bây giờ chúng ta có thể chạy:

     ng xây dựng --một - môi trường sản    

và tải lên thư mục đã tạo dist đến máy chủ lưu trữ của chúng tôi. Ngọt ngào thế nào?

Chúng tôi đã đề cập rất nhiều trong bài viết này, vì vậy chúng ta hãy tóm tắt lại những gì chúng tôi đã học.

Tóm tắt

Trong bài viết đầu tiên, chúng tôi đã học cách:

  • khởi tạo ứng dụng Todo của chúng tôi bằng cách sử dụng Angular CLI
  • tạo ra một lớp học Todo để đại diện cho các hoạt động của từng cá nhân
  • tạo một dịch vụ TodoDataService để tạo, cập nhật và xóa nội dung của việc làm
  • sử dụng thành phần AppComponent để hiển thị giao diện người dùng
  • triển khai ứng dụng của chúng tôi vào các trang GitHub

Trong bài báo thứ hai, chúng tôi đã tái cấu trúc lại AppComponent để ủy thác hầu hết các công việc của mình để:

  • a TodoListComponent để hiển thị một danh sách những điều cần làm
  • a TodoListItemComponent để hiển thị một thao tác đơn
  • a TodoListHeaderComponent để tạo ra một công việc mới
  • a TodoListFooterComponent để cho biết còn bao nhiêu thứ cần làm nữa

Trong bài báo thứ ba, chúng ta đã học cách:

  • tạo ra một phụ trợ REST API giả
  • lưu trữ các URL API như là một biến môi trường
  • tạo ApiService để liên lạc với REST API
  • cập nhật TodoDataService để sử dụng ApiService mới
  • Cập nhật AppComponent để xử lý cuộc gọi API không đồng bộ
  • tạo một ApiMockService để tránh các cuộc gọi HTTP thực sự khi chạy thử nghiệm đơn vị

Trong bài báo thứ tư này, chúng tôi đã học được:

  • tại sao một ứng dụng có thể cần định tuyến
  • một router JavaScript là gì
  • những gì Angular router, nó hoạt động như thế nào và những gì nó có thể làm cho bạn
  • làm thế nào để thiết lập Angular router và cấu hình các tuyến đường cho ứng dụng của chúng tôi
  • Làm thế nào để nói với Angular router nơi để đặt các thành phần trong DOM
  • làm thế nào để xử lý một cách duyên dáng các URL không rõ
  • làm thế nào để sử dụng một resolver để cho Angular router giải quyết dữ liệu

Tất cả mã từ bài này đều có tại https: // github. com / sitepoint-biên tập viên / góc-todo-app / cây / phần-4.

Trong phần năm, chúng tôi sẽ thực hiện xác thực để ngăn chặn truy cập trái phép vào ứng dụng của chúng tôi. com / avatar / ad9b5970be156b634406cb5c195cb6ec? s = 96 & d = mm & r = g "alt ="Giới thiệu về định tuyến các thành phần với Router gócGiới thiệu về định tuyến các thành phần với Router Hình Góc Chủ đề: Nguyên bản JavaScriptnpmTools & Semalt "/>

Gặp gỡ tác giả
Jurgen Van de Moere
Kiến trúc sư Mặt trận tại The Force - chuyên về JavaScript và AngularJS. Chuyên gia phát triển tại Google. Thể dục thể hình. Cha. Gia đình người đàn ông. Sáng tạo của Angular Express.
Giới thiệu về định tuyến các thành phần với Router gócGiới thiệu về định tuyến các thành phần với Router Hình Góc Chủ đề:
Nguyên bản JavaScriptnpmTools & Semalt
Khoá học trực tuyến cho Góc và LoạiScript
Phương châm Todd
Khóa học AngularJS, Angular và TypeScript trực tuyến do các chuyên gia dẫn đầu cho các cá nhân và đội. Sử dụng phiếu giảm giá 'SITEPOINT' lúc thanh toán để được giảm 25% .
March 1, 2018