From Article: RESOLVING ROUTE DATA IN ANGULAR 2

Github

If you know Anuglar UI router, you must know resolve function in ui router, which you can load data before template and controller get inited. In Angular2 router, you can also use resovler.

The recommended (personal preferred) way is use class to resolve the data, becasue you can inject servcie, so you can fetch data instead of hard cord data.

There is another way to use DI 'useValue'. Check out the article.

Create a resolver:

// hero-resolve.directive.ts

import {Resolve, ActivatedRouteSnapshot, RouterStateSnapshot} from "@angular/router";
import {Observable} from "rxjs";
import {StarWarsService} from "./heros.service";
import {Injectable} from "@angular/core"; @Injectable()
export class HeroDetailResolver implements Resolve<any> { constructor(private startWarsService: StarWarsService){ } resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | any{
const id = route.params['id'];
return this.startWarsService.getPersonDetail(id);
} }

After create the resovler, you can add to the providers:

@NgModule({
imports: [
CommonModule,
herosRoutes
],
declarations: [HerosComponent, HeroComponent],
providers: [StarWarsService, CanHeroDeactivate, CanHeroActivateDirective, HeroDetailResolver]
})

Routers:

import {HerosComponent} from "./heros.component";
import {RouterModule} from "@angular/router";
import {HeroComponent} from "./hero/hero.component";
import {CanHeroDeactivate} from "./heros-can-deactivate.directive";
import {CanHeroActivateDirective} from "./heros-can-activate.directive";
import {HeroDetailResolver} from "./hero-resolver.directive";
const routes = [
{path: '', component: HerosComponent},
{
path: ':id',
component: HeroComponent,
canDeactivate: [CanHeroDeactivate],
canActivate: [CanHeroActivateDirective],
resolve: {
hero: HeroDetailResolver
}
},
];
export default RouterModule.forChild(routes)

Here 'hero' will be used to fetch data from router data.

Component:

import {
Component,
OnInit,
OnDestroy,
ViewChild,
} from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {StarWarsService} from "../heros.service";
import {Observable, Subscription, BehaviorSubject} from "rxjs"; export interface Hero{
name: string,
image: string
} @Component({
selector: 'app-hero',
templateUrl: 'hero.component.html',
styleUrls: ['hero.component.css']
})
export class HeroComponent implements OnInit, OnDestroy { @ViewChild('inpRef') input; heroId: number;
hero: BehaviorSubject<Hero>;
description: string;
querySub: Subscription;
routeParam: Subscription;
editing: boolean = false; constructor(private route: ActivatedRoute,
private router: Router,
private starwarService: StarWarsService) { } ngOnInit() { /* // Old way to get data from service when component inited
this.hero = new BehaviorSubject({name: 'Loading...', image: ''}); this.route.params
.map((p:any) => {
this.editing = false;
this.heroId = p.id;
return p.id;
})
.switchMap( id => this.starwarService.getPersonDetail(id))
.subscribe( this.hero);*/ // Here using resolver instead of fetch on fly
this.routeParam = this.route.params
.map((p:any) => p.id)
.subscribe( (id) => {
this.editing = false;
this.heroId = id;
});
this.hero = this.route.data
.map((d:any)=> d['hero']);
} ngOnDestroy() {
this.querySub.unsubscribe();
this.routeParam.unsubscribe();
}
}

Child route and access parnet's router resolver's data

  {path: ':url/:id', children: [
{path: '', component: LessonDetailComponent},
{path: 'edit', component: EditLessonComponent}
], resolve: {
lesson: LessonDataResolver
}},

For 'LessonDetailComponent' and 'EditLessonComponent' can both access the resolve data:

    this.route.data
.subscribe(
(res) => {
this.lesson = res['lesson'];
}
)

ONE important note that: If return Observable from resolver, the observable should completed! Otherwise, it doesn't work. So why in the exmaple, it works, because $http.get(), it complete itself.

But if you use AngualrFire2, you fetch data from Firebase like:

  findLessonByUrl(url){
return this.angularFireRef.database.list('lessons', {
query: {
orderByChild: 'url',
equalTo: url
}
})
.filter(r => !!r)
.map(res => res[]);
}

The observable doesn't complete itself, so in the resolver, you need to find a way to make the observable completed.

For example:

import {Resolve, RouterStateSnapshot, ActivatedRouteSnapshot} from "@angular/router";
import {Observable} from "rxjs";
import {CourseService} from "../course.service";
import {Injectable} from "@angular/core"; @Injectable()
export class LessonDataResolver implements Resolve {
constructor(private lessonService: CourseService){ } resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
const url = route.params['id'];
return this.lessonService.findLessonByUrl(url).first();
} }

Here it calls .first() to complete the observable. Or you can use '.take(1)'.

[Angular2 Router] Resolving route data in Angular 2的更多相关文章

  1. [Angular2 Router] CanDeactivate Route Guard - How To Confirm If The User Wants To Exit A Route

    In this tutorial we are going to learn how we can to configure an exit guard in the Angular 2 Router ...

  2. [Angular2 Router] CanActivate Route Guard - An Example of An Asynchronous Route Guard

    In this tutorial we are going to learn how we can to configure an can activate route guard in the An ...

  3. [Angular2 Router] Optional Route Query Parameters - The queryParams Directive and the Query Parameters Observable

    In this tutorial we are going to learn how to use the Angular 2 router to pass optional query parame ...

  4. Angular2 - Starter - Routes, Route Resolver

    在基于Angualr的SPA中,路由是一个很重要的部分,它帮助我们更方便的实现页面上区域的内容的动态加载,不同tab的切换,同时及时更新浏览器地址栏的URN,使浏览器回退和前进能导航到历史访问的页面. ...

  5. [Angular2 Router] Preload lzay loading modules

    From router v3.1.0, we have preloading system with router. PreloadAllModules After the init module l ...

  6. [Angular2 Router] Setup page title with Router events

    Article import 'rxjs/add/operator/filter'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator ...

  7. [Angular2 Router] Programmatic Router Navigation via the Router API - Relative And Absolute Router Navigation

    In this tutorial we are going to learn how to navigate programmatically (or imperatively) by using t ...

  8. [Angular2 Router] Auxiliary Routes bit by bit

    Article Github Auxiliary Routes is is little bit hard to understand. Here is demo, link You can see ...

  9. Vue中美元$符号的意思与vue2.0中的$router 和 $route的区别

    vue的实例属性和方法 除了数据属性,Vue 实例还暴露了一些有用的实例属性与方法.它们都有前缀 $,以便与用户定义的属性区分开来.例如: var data = { a: 1 } var vm = n ...

随机推荐

  1. ATcoderARC100D Equal Cut

    ARC100 D - Equal Cut Description: 给出长度为n的序列A,把这个序列分成连续的四段,最小化极差. \(4≤n≤2×10^5,4≤n≤2×10^5\) Solution: ...

  2. 今日SGU 5.10

    SGU 168 题意:从a矩阵求出b矩阵,规则直接看题目就行了,不好打字说明 收获:dp #include<bits/stdc++.h> #define de(x) cout<< ...

  3. ln用法

    第一部分: 建立简单的硬连接: ln ./wwy.gif ./wwy_ln (第二个参数为新建的连接文件,建立前不存在),则任意一个文件变化,另一个也变化:大小为一个文件的大小:硬连接只能建在同一个分 ...

  4. [ReasonML] Named & optional params

    // ::country is named param // ::country=?: which make it optional // because we make ::country=? op ...

  5. Catch Me If You ... Can't Do Otherwise--转载

    原文地址:https://dzone.com/articles/catch-me-if-you-cant-do-otherwise I don't know whether it's an anti- ...

  6. Android Okhttp完美同步持久Cookie实现免登录

    通过对Retrofit2.0的<Retrofit 2.0 超能实践,完美支持Https传输>基础入门和案例实践,掌握了怎么样使用Retrofit访问网络,加入自定义header,包括加入S ...

  7. JavaScript--数据结构与算法之列表

    3.1 列表的抽象数据类型定义 列表:一组有序的数据.每个列表中的数据称为元素.在JavaScript中列表的元素可以是任意的数据类型.列表中保存的元素没有事先的限定,实际使用时的元素数量受到程序内存 ...

  8. vim学习2

    进入插入模式: 在插入模式下删除: 寄存器

  9. System.out.println 的多线程并发问题

    假设println函数的參数为常量则不会出现线程并发问题,可是假设參数为表达式形式.则JVM在运行println函数的时候会分为几步来运行,从而造成并发问题. 例如以下样例所看到的: package ...

  10. 题目1205:N阶楼梯上楼问题(2008年华中科技大学计算机保研机试真题:递推求解)

    题目1205:N阶楼梯上楼问题 时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:2447 解决:927 题目描写叙述: N阶楼梯上楼问题:一次能够走两阶或一阶,问有多少种上楼方式. (要求 ...