从 Angular Route 中提前获取数据的方法详解

 更新时间:2022年07月13日 11:05:15   作者:Jimmy  
这篇文章主要介绍了从 Angular Route 中提前获取数据,通过本文,你将学会使用 resolver, 在 Angular App 中应用 resolver,应用到一个公共的预加载导航,本文给大家介绍的非常详细,需要的朋友可以参考下

介绍

提前获取意味着在数据呈现在屏幕之前获取到数据。本文中,你将学到,在路由更改前怎么获取到数据。通过本文,你将学会使用 resolver, 在 Angular App 中应用 resolver,应用到一个公共的预加载导航。

你为什么应该使用 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

<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 中。效果如下快照。

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

总结

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

本文是译文,采用的是意译的方式,其中加上个人的理解和注释,原文地址是:www.pluralsight.com/guides/pref…

到此这篇关于从 Angular Route 中提前获取数据的文章就介绍到这了,更多相关Angular Route获取数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • AngularJs  Understanding Angular Templates

    AngularJs Understanding Angular Templates

    本文主要介绍AngularJs Understanding Angular Templates的资料,这里整理了详细的资料及简单示例代码,有兴趣的小伙伴的参考下
    2016-09-09
  • Angular4学习教程之HTML属性绑定的方法

    Angular4学习教程之HTML属性绑定的方法

    这篇文章主要给大家介绍了关于Angular4学习教程之HTML属性绑定的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-01-01
  • Angular实现form自动布局

    Angular实现form自动布局

    这篇文章主要介绍了Angular实现form自动布局的相关资料,以代码片段的形式分析了Angular实现form自动布局的实现方法,感兴趣的小伙伴们可以参考一下
    2016-01-01
  • 使用Angular9和TypeScript开发RPG游戏的方法

    使用Angular9和TypeScript开发RPG游戏的方法

    这篇文章主要介绍了使用Angular9和TypeScript开发RPG游戏的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • AngularJS中的DOM操作用法分析

    AngularJS中的DOM操作用法分析

    这篇文章主要介绍了AngularJS中的DOM操作,较为详细的分析了AngularJS针对DOM操作的原理、实现技巧与相关注意事项,需要的朋友可以参考下
    2016-11-11
  • AngularJS数据源的多种获取方式汇总

    AngularJS数据源的多种获取方式汇总

    在AngularJS中获取数据源的方式有很多种,本文给大家整理几种获取数据源的方式,对angularjs获取数据源的方式相关知识感兴趣的朋友一起学习吧
    2016-02-02
  • angularJs使用ng-repeat遍历后选中某一个的方法

    angularJs使用ng-repeat遍历后选中某一个的方法

    今天小编就为大家分享一篇angularJs使用ng-repeat遍历后选中某一个的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • Angular 2使用路由自定义弹出组件toast操作示例

    Angular 2使用路由自定义弹出组件toast操作示例

    这篇文章主要介绍了Angular 2使用路由自定义弹出组件toast操作,结合实例形式分析了Angular2使用路由操作弹出组件toast相关定义与使用技巧,需要的朋友可以参考下
    2019-05-05
  • AngularJS中的Directive自定义一个表格

    AngularJS中的Directive自定义一个表格

    本篇文章给大家介绍在angularjs中自定义一个有关表格的directive,涉及到angularjs directive相关知识,对本文感兴趣的朋友一起学习吧
    2016-01-01
  • AngularJS实现的生成随机数与猜数字大小功能示例

    AngularJS实现的生成随机数与猜数字大小功能示例

    这篇文章主要介绍了AngularJS实现的生成随机数与猜数字大小功能,结合完整实例形式分析了AngularJS随机数生成与数值判定相关操作技巧,需要的朋友可以参考下
    2017-12-12

最新评论