您好,登錄后才能下訂單哦!
這篇文章主要講解了“Angular Route中如何提前獲取數據”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Angular Route中如何提前獲取數據”吧!
提前獲取意味著在數據呈現在屏幕之前獲取到數據。
Resolver
Resolver
在路由跟組件之間扮演著中間件服務的角色。假設你有一個表單,沒有數據時,你想向用戶一個空的表單,當在加載用戶數據時展示一個 loader
,然后當數據返回時,填充表單并隱藏 loader
。
通常,我們都會在組件的 ngOnInit()
鉤子函數中獲取數據。也就是說,組件加載完之后,我們發起數據請求。
在 ngOnInit()
中操作,我們需要在每個需要的組件加載后,在其路由頁面中添加 loader
展示。Resolver
可以簡化 loader
的添加使用。你可以只添加一個適用于每個路由的 loader
,而不是每個路由中都添加 loader
。
本文將結合示例來解析 resolver
的知識點。以便于你可以牢記它并在項目中使用它。
Resolver
為了在應用中使用 resolver
,你需要準備一些接口。你可以通過 JSONPlaceholder 來模擬,而不需要自己開發。
JSONPlaceholder
是一個很棒的接口資源,你可以借助它更好學習前端的相關概念而不被接口所約束。
現在,接口的問題解決了,我們可以開始 resolver
的應用了。一個 resolver
就是一個中間件服務,所以我們將創建一個服務。
$ ng g s resolvers/demo-resolver --skipTests=true
--skipTests=true 跳過生成測試文件
src/app/resolvers
文件夾中創建了一個服務。resolver
接口中有一個 resolve()
方法,它有兩個參數:route
(ActivatedRouteSnapshot
的實例)和 state
(RouterStateSnapshot
的實例)。
loader
通常是在 ngOnInit()
中編寫所有的 AJAX
請求,但是邏輯將會在 resolver
中實現,替代 ngOnInit()
。
接著,創建一個服務來獲取 JSONPlaceholder
中列表數據。然后在 resolver
中底調用,接著在路由中配置 resolve
信息,(頁面將會等待)直到 resolver
被處理。在 resolver
被處理之后,我們可以通過路由來獲取數據然后展示在組件中。
$ ng g s services/posts --skipTests=true
現在,我們成功創建了服務,是時候編寫一個 AJAX
請求的邏輯了。
model
的使用能夠幫助我們減少錯誤。
$ ng g class models/post --skipTests=true
post.ts
export class Post { id: number; title: string; body: string; userId: string; }
model
就緒,是時候獲取帖子 post
的數據了。
post.service.ts
import { Injectable } from "@angular/core"; import { HttpClient } from "@angular/common/http"; import { Post } from "../models/post"; @Injectable({ providedIn: "root" }) export class PostsService { constructor(private _http: HttpClient) {} getPostList() { let URL = "https://jsonplaceholder.typicode.com/posts"; return this._http.get<Post[]>(URL); } }
現在,這個服務隨時可被調用。
demo-resolver.service.ts
import { Injectable } from "@angular/core"; import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from "@angular/router"; import { PostsService } from "../services/posts.service"; @Injectable({ providedIn: "root" }) export class DemoResolverService implements Resolve<any> { constructor(private _postsService: PostsService) {} resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { return this._postsService.getPostList(); } }
帖子列表數據從 resolver
中返回。現在,你需要一個路由去配置 resolver
,從路由獲取數據,然后讓數據展示在組件中。為了進行路由跳轉,我們需要創建一個組件。
$ ng g c components/post-list --skipTests=true
為了路由可見,在 app.component.ts
添加 router-outlet
。
<router-outlet></router-outlet>
現在,你可以配置 app-routing.module.ts
文件了。下面的片段代碼將有助于你理解路由配置 resolver
。
app-routing-module.ts
import { NgModule } from "@angular/core"; import { Routes, RouterModule } from "@angular/router"; import { PostListComponent } from "./components/post-list/post-list.component"; import { DemoResolverService } from "./resolvers/demo-resolver.service"; const routes: Routes = [ { path: "posts", component: PostListComponent, resolve: { posts: DemoResolverService } }, { path: "", redirectTo: "posts", pathMatch: "full" } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule {}
一個 resolve
已經添加到路由配置中了,它將發起一個 HTTP
請求,然后當 HTTP
請求成功返回后,允許組件初始化。路由將組裝獲取到的 HTTP
請求返回的數據。
向用戶展示一個請求正在進行,我們在 AppComponent
中編寫一個公共且簡單的 loader
。你可以根據需要自定義。
app.component.html
<div class="loader" *ngIf="isLoader"> <div>Loading...</div> </div> <router-outlet></router-outlet>
app.component.ts
import { Component } from "@angular/core"; import { Router, RouterEvent, NavigationStart, NavigationEnd } from "@angular/router"; @Component({ selector: "app-root", templateUrl: "./app.component.html", styleUrls: ["./app.component.scss"] }) export class AppComponent { isLoader: boolean; constructor(private _router: Router) {} ngOnInit() { this.routerEvents(); } routerEvents() { this._router.events.subscribe((event: RouterEvent) => { switch (true) { case event instanceof NavigationStart: { this.isLoader = true; break; } case event instanceof NavigationEnd: { this.isLoader = false; break; } } }); } }
當導航開始,isLoader
值被賦予 true
,頁面中,你將看到下面的效果。
當 resolver
處理完之后,它將會被隱藏。
現在,是時候從路由中獲取值并將其展示出來。
port-list.component.ts
import { Component, OnInit } from "@angular/core"; import { Router, ActivatedRoute } from "@angular/router"; import { Post } from "src/app/models/post"; @Component({ selector: "app-post-list", templateUrl: "./post-list.component.html", styleUrls: ["./post-list.component.scss"] }) export class PostListComponent implements OnInit { posts: Post[]; constructor(private _route: ActivatedRoute) { this.posts = []; } ngOnInit() { this.posts = this._route.snapshot.data["posts"]; } }
如上所示,post
的值來自 ActivatedRoute
的快照信息 data
。這值都可以獲取,只要你在路由中配置了相同的信息。
我們在 HTML
進行如下渲染。
<div class="post-list grid-container"> <div class="card" *ngFor="let post of posts"> <div class="title"><b>{{post?.title}}</b></div> <div class="body">{{post.body}}</div> </div> </div>
CSS
片段樣式讓其看起來更美觀。
port-list.component.css
.grid-container { display: grid; grid-template-columns: calc(100% / 3) calc(100% / 3) calc(100% / 3); } .card { margin: 10px; box-shadow: black 0 0 2px 0px; padding: 10px; }
推薦使用 scss 預處理器編寫樣式
從路由中獲取數據之后,它會被展示在 HTML
中。效果如下快照。
感謝各位的閱讀,以上就是“Angular Route中如何提前獲取數據”的內容了,經過本文的學習后,相信大家對Angular Route中如何提前獲取數據這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。