首頁  >  文章  >  web前端  >  聊聊Angular Route中怎麼提前取得數據

聊聊Angular Route中怎麼提前取得數據

青灯夜游
青灯夜游轉載
2022-07-13 20:00:501880瀏覽

Angular Route中怎麼提前取得數據?以下這篇文章為大家介紹一下從 Angular Route 提前取得數據的方法,希望對大家有幫助!

聊聊Angular Route中怎麼提前取得數據

提前取得意味著在資料呈現在螢幕之前取得到資料。本文中,你將學到,在路由更改前怎麼取得到資料。透過本文,你將學會使用 resolver, 在 Angular App 中應用 resolver,應用到一個公共的預先載入導航。 【相關教學推薦:《angular教學》】

你為什麼應該使用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() 方法,它有兩個參數:routeActivatedRouteSnapshot 的實例)和 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

Loading...
<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,页面中,你将看到下面的效果。

聊聊Angular Route中怎麼提前取得數據

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中怎麼提前取得數據

至此,你已经了解完怎么应用 resolver 在你的项目中了。

总结

结合用户体验设计,在 resolver 的加持下,你可以提升你应用的表现。了解更多,你可以戳官网

本文是译文,采用的是意译的方式,其中加上个人的理解和注释,原文地址是:

https://www.pluralsight.com/guides/prefetching-data-for-an-angular-route

更多编程相关知识,请访问:编程视频!!

以上是聊聊Angular Route中怎麼提前取得數據的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除