程序员

Angular——resolve基础用法

2018-09-18  本文已影响33人  Switchhh

参考Angular中文网 <Resolve: 预先获取组件数据>
API地址 <resolve守卫>

一、使用场景

resolve保证了数据获取后再进行路由跳转,防止因为数据延迟而出现短暂的空组件情况,以此增强用户体验。

应用resolve还可以进行路由拦截,例如某些网站如果用户未登录,在跳转到某一页面时会提示未登录然后强行回跳至前一页面,这时如果使用resolve就可以在跳转发生前判断登录状态以决定是否允许跳转。


二、基础用法

示例中跳转逻辑为home.component => resolve.service => detail.component

home-routing.module.ts

import { NgModule }             from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { DetailResolver }       from './detail-resolver.service';
import { DetailComponent }      from './detail.component';

const routes: Routes = [
  {
    path: ':id',
    component: DetailComponent,
    resolve: { // 此处使用resolve
      detail: DetailResolver
    }
  },
];
@NgModule({
  imports: [
    RouterModule.forChild(routes)
  ],
  exports: [
    RouterModule
  ],
  providers: [
    DetailResolver
  ]
})
export class HomeRoutingModule { }

detail-resolver.service.ts

import { Injectable }             from '@angular/core';
import { Router, Resolve, RouterStateSnapshot,
         ActivatedRouteSnapshot } from '@angular/router';
import { Observable }             from 'rxjs';
import { map, take }              from 'rxjs/operators';

import { detail, DetailService }  from './detail.service';

@Injectable()
export class DetailResolver implements Resolve<Detail> {
  constructor(private detailService: DetailService, private router: Router) {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Detail> {
    let id = route.paramMap.get('id');

    return this.detailService.getDetail(id).pipe(
      take(1), // 可选,只发出源 Observable 最初发出的的1个值
      map(res => {
        if (res) {
          return res;
        } else { // 请求失败时拦截跳转
          this.router.navigate(['/home']);
          return null;
        }
      })
    );
  }
}

由路由器提供的 Observable 必须完成,否则导航不会继续。

detail.component.ts

// 通过 route 获取 detail-resolver.service 中 detailService.getDetail 请求的数据
ngOnInit() {
  this.route.data
    .subscribe((data: { detail: Detail }) => {
      this.detail = data.detail; 
    });
}
上一篇下一篇

猜你喜欢

热点阅读