在Angular2路由中使用Resolve

在Angular2路由中使用Resolve,angular,angular2-routing,Angular,Angular2 Routing,在Angular 1中,我的配置如下所示: $routeProvider .when("/news", { templateUrl: "newsView.html", controller: "newsController", resolve: { message: function(messageService){ return messageService.getMessage(); } } }) 如何在Ang

在Angular 1中,我的配置如下所示:

$routeProvider
  .when("/news", {
    templateUrl: "newsView.html",
    controller: "newsController",
    resolve: {
        message: function(messageService){
            return messageService.getMessage();
    }
  }
})

如何在Angular2中使用resolve?

正如alexpods已经提到的,似乎没有这样的“resolve”。这个想法似乎是利用路由器提供的生命周期挂钩。这些是:

  • 可重复使用
  • 烛台
  • 激活
  • 再利用
  • 激活
然后是@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中,而不是存储在“下一个”组件中。这是因为,onActivate也仅在next和previous中调用,而不是承诺的结果。 我对这个解决方案不满意,但这是我能想到的最好的解决方案。

“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
    }
  }])
);
类TeamResolver实现解析{
构造函数(专用后端:后端){}
解析(路由:ActivatedRouteSnapshot,状态:RouterStateSnashot):可观察{
返回this.backend.fetchTeam(this.route.params.id);
}
}
引导程序(AppComponent[
团队分解器,
供应商外部([{
路径:'team/:id',
组成部分:TeamCmp,
决心:{
团队:团队解决者
}
}])
);

基于@angular/router v3 beta版,以下是必需的步骤

实现一个返回可观察值或普通值的解析器:

@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));
    }

}
将冲突解决程序添加到路由:

export const HeroesRoutes: RouterConfig = [
    { path: 'heroes',  component: HeroListComponent, resolve: { heroes: HeroesResolver } },
    { path: 'hero/:id', component: HeroDetailComponent, resolve: { hero: HeroResolver } }
];
最后,提供您的resolve类以及对引导程序或主组件
提供程序的任何依赖项

bootstrap(AppComponent, [
    HeroesResolver, HeroService
])
使用ActivateRoute实例中解析的数据:

ngOnInit() {
    this.hero = this.route.snapshot.data['hero'];
}
请记住,快照是指组件类和解析器类中处于执行状态的值。
使用此方法无法从参数更新中刷新数据

普朗克:
资料来源:

@AndréWerlang的回答很好,但如果您希望在route参数更改时更改页面上已解析的数据,则需要:

解析器:

@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+中创建解析器,并将其应用于路由器。请看下面的内容,以下是在Angular2+中创建解析器的方法:

@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);
  }
}
最后,在您的组件中:

ngOnInit() {
  this.route.data.subscribe((data: { about: About }) => {
    this.about = data.about;
  });
}

假设此功能尚未实现。请注意。现在您可以尝试使用和
@OnActivate
挂钩(但当然不是
解析
功能)。仅供参考,挂钩可能是routerOnActivate(至少在ES6/7中)如何注入
messageService
?我正在尝试使用
Injector.resolveAndCreate()
。它显然无法为正在创建的服务提供
bootstrap()
中指定的应用程序范围的依赖项。结果是“没有Http提供程序”,例如,或我的服务需要的其他东西。我也很感兴趣,你如何将服务的依赖注入
@CanActivate
?@shannon我在@CanActivate这样的装饰器中找到了DI的解决方案。使用
bootstrap
中的承诺保存对appInjector的引用,并使用该承诺进行注入。查看此链接:如何这可以在RC中完成?RC退出后,现在有更好的方法吗?虽然此链接可以回答问题,但最好在此处包含答案的基本部分,并提供链接供参考。如果链接页面发生更改,则仅链接的答案可能无效。-谢谢,@RichardTelford!仍在这里学习最佳做法。W问:为什么我在只读模式下使用stackoverflow已经超过十年了…:)好的,这显示了如何在组件实例化之前进行查询,但是如何/从何处访问组件中的解析值?我在
ActivatedRoute
中找到了解析值,您必须将其注入组件中。解析值存储在属性上:
route.snapshot.data
。我也暂时放弃解析。在我的情况下,我希望在路由器防护的
canActivate
方法之前进行解析,但防护总是首先被调用:(@kishorelangi
import{resolve}from“@angular/router”
能否将服务
导入{HeroService}作为heroSvc从./hero.service'
导入路由并执行
解析:{heros:heroSvc.getheros()}
?@Baruch您不能。解析中的任何内容都被用作DI的标记。这通常是一个类,但也可以是一个字符串,甚至是一个函数引用。但是因为您需要先提供它,所以它不会按照您的意图工作。是否可以将
hero
作为参数直接注入构造函数中?“使用此方法无法从params更新中刷新数据。”哪种方法适用于params更新?我在下面回答了自己的问题!
export const Routes: RouterConfig = [
  { path: 'about',  component: AboutComponent, resolve: { data: AboutResolver } }
]; 
ngOnInit() {
  this.route.data.subscribe((data: { about: About }) => {
    this.about = data.about;
  });
}