在 Angular2 路由中使用 Resolve
Using Resolve In Angular2 Routes
在 Angular 1 中,我的配置如下所示:
$routeProvider
.when("/news", {
templateUrl: "newsView.html",
controller: "newsController",
resolve: {
message: function(messageService){
return messageService.getMessage();
}
}
})
如何在 Angular2 中使用解析?
正如 alexpods 已经提到的,似乎没有 'resolve' 这样的。这个想法似乎是您利用路由器提供的生命周期挂钩。它们是:
- 可以重复使用
- 可以停用
- onActivate
- 重用
- 停用
然后是@CanActivate。这是一个特殊的钩子,因为它在您的组件被实例化之前被调用。它的参数是 (next, previous)
,分别是你要路由到的组件和你来自的组件(如果你没有历史,则为 null)。
import {Component} from '@angular/core';
import {ROUTER_DIRECTIVES, CanActivate, OnActivate} from '@angular/router';
@Component({
selector: 'news',
templateUrl: 'newsView.html',
directives: [ROUTER_DIRECTIVES]
})
@CanActivate((next) => {
return messageService.getMessage()
.then((message) => {
next.params.message = message;
return true; //truthy lets route continue, false stops routing
});
})
export class Accounts implements OnActivate {
accounts:Object;
onActivate(next) {
this.message = next.params.message;
}
}
我还没有弄清楚的是如何将承诺的结果放入您的 onActivate - 而不是将其存储在您的 'next' 组件中。这是因为 onActivate 也仅通过 next 和 previous 调用,而不是承诺的结果。
我对那个解决方案不满意,但这是我能想到的最好的解决方案。
https://angular.io/docs/ts/latest/api/router/index/Resolve-interface.html
"resolve" 已被带回 angular2 路由器,但文档很少。
示例:
class TeamResolver implements Resolve {
constructor(private backend: Backend) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<any> {
return this.backend.fetchTeam(this.route.params.id);
}
}
bootstrap(AppComponent, [
TeamResolver,
provideRouter([{
path: 'team/:id',
component: TeamCmp,
resolve: {
team: TeamResolver
}
}])
);
基于@angular/router v3-beta,这些是必需的步骤。
实现一个 return 是 Observable 或普通值的解析器:
@Injectable()
export class HeroResolver implements Resolve {
constructor(
private service: HeroService
) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Hero> {
const id = +route.params['id'];
return Observable.fromPromise(this.service.getHero(id));
}
}
请注意,如果您 return 一个 observable,解包值(第一个)将通过 route.snapshot.data
可用。
如果你想让 Observable 本身可用,那么你需要将它包装在另一个 Observable 中:
return Observable.of(source$);
将解析器添加到您的路由:
export const HeroesRoutes: RouterConfig = [
{ path: 'heroes', component: HeroListComponent, resolve: { heroes: HeroesResolver } },
{ path: 'hero/:id', component: HeroDetailComponent, resolve: { hero: HeroResolver } }
];
最后,提供您的解决方案 class 以及对 bootstrap 或您的主要组件 providers
的任何依赖:
bootstrap(AppComponent, [
HeroesResolver, HeroService
])
使用来自 ActivatedRoute 实例的已解析数据:
ngOnInit() {
this.hero = this.route.snapshot.data['hero'];
}
请记住,快照是指执行状态下的值,在组件 class 和解析器 class 中都是如此。
使用此方法无法从参数更新中刷新数据。
笨蛋:http://plnkr.co/edit/jpntLjrNOgs6eSFp1j1P?p=preview
来源 material:https://github.com/angular/angular/commit/f2f1ec0#diff-a19f4d51bb98289ab777640d9e8e5006R436
@AndréWerlang 的回答很好,但是如果你想让页面上的解析数据随着路由参数变化而变化,你需要:
解析器:
@Injectable()
export class MessageResolver implements Resolve<Message> {
constructor(private messageService: MessageService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Message> {
const id = +route.params['id'];
return this.messageService.getById(id);
}
}
您的组件:
ngOnInit() {
this.route.data.subscribe((data: { message: Message }) => {
this.message = data.message;
});
}
您可以在 Angular2+ 中创建您的 Resolver 并将其很容易地应用于路由器。看下面,这是在 Angular:
中创建 Resolver 的方法
@Injectable()
export class AboutResolver implements Resolve<Message> {
constructor(private aboutService: AboutService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
const id = route.params['id'];
return this.aboutService.getById(id);
}
}
然后在路由器配置中:
export const Routes: RouterConfig = [
{ path: 'about', component: AboutComponent, resolve: { data: AboutResolver } }
];
最后在您的组件中:
ngOnInit() {
this.route.data.subscribe((data: { about: About }) => {
this.about = data.about;
});
}
在 Angular 1 中,我的配置如下所示:
$routeProvider
.when("/news", {
templateUrl: "newsView.html",
controller: "newsController",
resolve: {
message: function(messageService){
return messageService.getMessage();
}
}
})
如何在 Angular2 中使用解析?
正如 alexpods 已经提到的,似乎没有 'resolve' 这样的。这个想法似乎是您利用路由器提供的生命周期挂钩。它们是:
- 可以重复使用
- 可以停用
- onActivate
- 重用
- 停用
然后是@CanActivate。这是一个特殊的钩子,因为它在您的组件被实例化之前被调用。它的参数是 (next, previous)
,分别是你要路由到的组件和你来自的组件(如果你没有历史,则为 null)。
import {Component} from '@angular/core';
import {ROUTER_DIRECTIVES, CanActivate, OnActivate} from '@angular/router';
@Component({
selector: 'news',
templateUrl: 'newsView.html',
directives: [ROUTER_DIRECTIVES]
})
@CanActivate((next) => {
return messageService.getMessage()
.then((message) => {
next.params.message = message;
return true; //truthy lets route continue, false stops routing
});
})
export class Accounts implements OnActivate {
accounts:Object;
onActivate(next) {
this.message = next.params.message;
}
}
我还没有弄清楚的是如何将承诺的结果放入您的 onActivate - 而不是将其存储在您的 'next' 组件中。这是因为 onActivate 也仅通过 next 和 previous 调用,而不是承诺的结果。 我对那个解决方案不满意,但这是我能想到的最好的解决方案。
https://angular.io/docs/ts/latest/api/router/index/Resolve-interface.html "resolve" 已被带回 angular2 路由器,但文档很少。
示例:
class TeamResolver implements Resolve {
constructor(private backend: Backend) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<any> {
return this.backend.fetchTeam(this.route.params.id);
}
}
bootstrap(AppComponent, [
TeamResolver,
provideRouter([{
path: 'team/:id',
component: TeamCmp,
resolve: {
team: TeamResolver
}
}])
);
基于@angular/router v3-beta,这些是必需的步骤。
实现一个 return 是 Observable 或普通值的解析器:
@Injectable()
export class HeroResolver implements Resolve {
constructor(
private service: HeroService
) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Hero> {
const id = +route.params['id'];
return Observable.fromPromise(this.service.getHero(id));
}
}
请注意,如果您 return 一个 observable,解包值(第一个)将通过 route.snapshot.data
可用。
如果你想让 Observable 本身可用,那么你需要将它包装在另一个 Observable 中:
return Observable.of(source$);
将解析器添加到您的路由:
export const HeroesRoutes: RouterConfig = [
{ path: 'heroes', component: HeroListComponent, resolve: { heroes: HeroesResolver } },
{ path: 'hero/:id', component: HeroDetailComponent, resolve: { hero: HeroResolver } }
];
最后,提供您的解决方案 class 以及对 bootstrap 或您的主要组件 providers
的任何依赖:
bootstrap(AppComponent, [
HeroesResolver, HeroService
])
使用来自 ActivatedRoute 实例的已解析数据:
ngOnInit() {
this.hero = this.route.snapshot.data['hero'];
}
请记住,快照是指执行状态下的值,在组件 class 和解析器 class 中都是如此。 使用此方法无法从参数更新中刷新数据。
笨蛋:http://plnkr.co/edit/jpntLjrNOgs6eSFp1j1P?p=preview 来源 material:https://github.com/angular/angular/commit/f2f1ec0#diff-a19f4d51bb98289ab777640d9e8e5006R436
@AndréWerlang 的回答很好,但是如果你想让页面上的解析数据随着路由参数变化而变化,你需要:
解析器:
@Injectable()
export class MessageResolver implements Resolve<Message> {
constructor(private messageService: MessageService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Message> {
const id = +route.params['id'];
return this.messageService.getById(id);
}
}
您的组件:
ngOnInit() {
this.route.data.subscribe((data: { message: Message }) => {
this.message = data.message;
});
}
您可以在 Angular2+ 中创建您的 Resolver 并将其很容易地应用于路由器。看下面,这是在 Angular:
中创建 Resolver 的方法@Injectable()
export class AboutResolver implements Resolve<Message> {
constructor(private aboutService: AboutService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
const id = route.params['id'];
return this.aboutService.getById(id);
}
}
然后在路由器配置中:
export const Routes: RouterConfig = [
{ path: 'about', component: AboutComponent, resolve: { data: AboutResolver } }
];
最后在您的组件中:
ngOnInit() {
this.route.data.subscribe((data: { about: About }) => {
this.about = data.about;
});
}