[Angular2 Router] Resolving route data in Angular 2
From Article: RESOLVING ROUTE DATA IN ANGULAR 2
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的更多相关文章
- [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 ...
- [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 ...
- [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 ...
- Angular2 - Starter - Routes, Route Resolver
在基于Angualr的SPA中,路由是一个很重要的部分,它帮助我们更方便的实现页面上区域的内容的动态加载,不同tab的切换,同时及时更新浏览器地址栏的URN,使浏览器回退和前进能导航到历史访问的页面. ...
- [Angular2 Router] Preload lzay loading modules
From router v3.1.0, we have preloading system with router. PreloadAllModules After the init module l ...
- [Angular2 Router] Setup page title with Router events
Article import 'rxjs/add/operator/filter'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator ...
- [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 ...
- [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 ...
- Vue中美元$符号的意思与vue2.0中的$router 和 $route的区别
vue的实例属性和方法 除了数据属性,Vue 实例还暴露了一些有用的实例属性与方法.它们都有前缀 $,以便与用户定义的属性区分开来.例如: var data = { a: 1 } var vm = n ...
随机推荐
- Kali的源得数字验证问题
装上之后第一件事就是执行apt-get update && apt-get upgrade,结果却出现了这样的错误 我添加的是中科大的更新源,在浏览器中是可以正常打开的: deb ht ...
- locate---查找文件
- 03006_DOS操作数据乱码解决
1.我们在dos命令行操作中文时,会报错 insert into sort(sid,sname) values(2,"电视机"); ERROR 1366 (HY000): Inco ...
- TYVJ P1153 间谍网络
P1153 间谍网络 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 由于外国间谍的大量渗入,国家安全正处于高度危机之中.如果A间谍手中掌握着关于B间谍的犯罪 ...
- PHP类中的__get()和__set函数到底有什么用
PHP类中的__get()和__set函数到底有什么用 一.总结 一句话总结:当试图获取一个不可达变量时,类会自动调用__get.同样的,当试图设置一个不可达变量时,类会自动调用__set.在网站中, ...
- 父子margin塌陷
1.使用padding 2.给父级使用border 3.给父级添加属性 overflow:hidden 4.浮动 5.定位{absolute,fixed} 6.伪元素代码 .parent:before ...
- PatentTips - Interrupt redirection for virtual partitioning
BACKGROUND The present disclosure relates to the handling of interrupts in a environment that utiliz ...
- C++面试必备,概念解析
1.C和C++中struct有什么差别? 1> C++中的struct类似于class,有变量.有构造函数.虚函数等.有继承,多态等类的特征: 2> C中的struct仅仅有变量,不能有函 ...
- [Javascript] Different ways to create an new array/object based on existing array/object
Array: 1. slice() const newAry = ary.slice() 2. concat const newAry = [].concat(ary) 3. spread oprea ...
- CSS3制作W3cplus的关注面板
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...