Angular Route中如何提前获取数据
导读:本文共4935.5字符,通常情况下阅读需要16分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要: 提前获取意味着在数据呈现在屏幕之前获取到数据。你为什么应该使用 ResolverResolver 在路由跟组件之间扮演着中间件服务的角色。假设你有一个表单,没有数据时,你想向用户一个空的表单,当在加载用户数据时展示一个 loader,然后当数据返回时,填充表单并隐藏 loader。通常,我们都会在组件的 ngOnInit() 钩子函数中获取数据。也就是说,组件加... ...
目录
(为您整理了一些要点),点击可以直达。提前获取意味着在数据呈现在屏幕之前获取到数据。
你为什么应该使用 Resolver
Resolver
在路由跟组件之间扮演着中间件服务的角色。假设你有一个表单,没有数据时,你想向用户一个空的表单,当在加载用户数据时展示一个 loader
,然后当数据返回时,填充表单并隐藏 loader
。
通常,我们都会在组件的 ngOnInit()
钩子函数中获取数据。也就是说,组件加载完之后,我们发起数据请求。
在 ngOnInit()
中操作,我们需要在每个需要的组件加载后,在其路由页面中添加 loader
展示。Resolver
可以简化 loader
的添加使用。你可以只添加一个适用于每个路由的 loader
,而不是每个路由中都添加 loader
。
本文将结合示例来解析 resolver
的知识点。以便于你可以牢记它并在项目中使用它。
在应用中使用 Resolver
为了在应用中使用 resolver
,你需要准备一些接口。你可以通过 JSONPlaceholder 来模拟,而不需要自己开发。
JSONPlaceholder
是一个很棒的接口资源,你可以借助它更好学习前端的相关概念而不被接口所约束。
现在,接口的问题解决了,我们可以开始 resolver
的应用了。一个 resolver
就是一个中间件服务,所以我们将创建一个服务。
$nggsresolvers/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
被处理之后,我们可以通过路由来获取数据然后展示在组件中。
创建服务并编写逻辑获取列表数据
$nggsservices/posts--skipTests=true
现在,我们成功创建了服务,是时候编写一个 AJAX
请求的逻辑了。
model
的使用能够帮助我们减少错误。
$nggclassmodels/post--skipTests=true
post.ts
exportclassPost{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"})exportclassPostsService{constructor(private_http:HttpClient){}getPostList(){letURL="https://jsonplaceholder.typicode.com/posts";returnthis._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"})exportclassDemoResolverServiceimplementsResolve<any>{constructor(private_postsService:PostsService){}resolve(route:ActivatedRouteSnapshot,state:RouterStateSnapshot){returnthis._postsService.getPostList();}}
帖子列表数据从 resolver
中返回。现在,你需要一个路由去配置 resolver
,从路由获取数据,然后让数据展示在组件中。为了进行路由跳转,我们需要创建一个组件。
$nggccomponents/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";constroutes:Routes=[{path:"posts",component:PostListComponent,resolve:{posts:DemoResolverService}},{path:"",redirectTo:"posts",pathMatch:"full"}];@NgModule({imports:[RouterModule.forRoot(routes)],exports:[RouterModule]})exportclassAppRoutingModule{}
一个 resolve
已经添加到路由配置中了,它将发起一个 HTTP
请求,然后当 HTTP
请求成功返回后,允许组件初始化。路由将组装获取到的 HTTP
请求返回的数据。
怎么应用一个预加载导航
向用户展示一个请求正在进行,我们在 AppComponent
中编写一个公共且简单的 loader
。你可以根据需要自定义。
app.component.html
<divclass="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"]})exportclassAppComponent{isLoader:boolean;constructor(private_router:Router){}ngOnInit(){this.routerEvents();}routerEvents(){this._router.events.subscribe((event:RouterEvent)=>{switch(true){caseeventinstanceofNavigationStart:{this.isLoader=true;break;}caseeventinstanceofNavigationEnd:{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"]})exportclassPostListComponentimplementsOnInit{posts:Post[];constructor(private_route:ActivatedRoute){this.posts=[];}ngOnInit(){this.posts=this._route.snapshot.data["posts"];}}
如上所示,post
的值来自 ActivatedRoute
的快照信息 data
。这值都可以获取,只要你在路由中配置了相同的信息。
我们在 HTML
进行如下渲染。
<divclass="post-listgrid-container"><divclass="card"*ngFor="letpostofposts"><divclass="title"><b>{{post?.title}}</b></div><divclass="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:black002px0px;padding:10px;}
推荐使用 scss 预处理器编写样式
从路由中获取数据之后,它会被展示在 HTML
中。效果如下快照。
</div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
Angular Route中如何提前获取数据的详细内容,希望对您有所帮助,信息来源于网络。