在 Angular 2 中为路由的通用组件提供异步依赖项.路由的解析等效项

Provide async dependencies to route's generic components in Angular 2. Route's resolve equivalent

本文关键字:路由 依赖 异步 组件 Angular      更新时间:2023-09-26

我想提供一组通用组件,这样它们就不会知道提供依赖关系的服务。依赖关系 这样的组件是承诺。换句话说,我希望将数据访问排除在这些通用组件的范围之外。任何依赖项(尤其是要呈现的数据和组件配置(都应由声明组件的上下文提供给组件。当我将视图中的组件声明为 DOM 标签时,这很容易,例如:

<generic-component data="getSomeData()" configuration="componentConfig"></generic-component>

但是当组件直接调用为路由时,我如何处理呢?

我读过非常相似的问题,但对这个问题的回答绝对不能让我满意。接受将依赖项放入组件的答案建议,但这意味着失去组件的通用方式。

在 Angular 1 中,这样做的方法是使用路由声明resolve属性。在 Angular 2 中,Angular 的 1 解析相当于什么?

请参考上述问题的示例,因为它非常准确。

RC 4 中的 Angular 2 引入了 Route 的解析属性。

此属性是具有实现解析接口的属性的对象。

每个解析器都必须@Injectable,并且具有返回 Observable|承诺|任何。

当您将 Activated Route 作为route注入到组件中时,您可以从 route.snapshod.data['someResolveKey'] 访问每个解析的属性。

angular.io 文档中的示例:

class Backend {
  fetchTeam(id: string) {
    return 'someTeam';
  }
}
@Injectable()
class TeamResolver implements Resolve<Team> {
  constructor(private backend: Backend) {}
  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any>|Promise<any>|any {
    return this.backend.fetchTeam(route.params.id);
  }
}
@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: 'team/:id',
        component: TeamCmp,
        resolve: {
          team: TeamResolver
        }
      }
    ])
  ],
  providers: [TeamResolver]
})
class AppModule {}

或者,您还可以提供具有相同签名的函数而不是类。

@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: 'team/:id',
        component: TeamCmp,
        resolve: {
          team: 'teamResolver'
        }
      }
    ])
  ],
  providers: [
    {
      provide: 'teamResolver',
      useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => 'team'
    }
  ]
})
class AppModule {}

您可以在组件中获取数据:

export class SomeComponent implements OnInit {
    resource : string;
    team : string;
    constructor(private route: ActivatedRoute) {
    }
    ngOnInit() {
        this.team = this.route.snapshot.data['team'];
        // UPDATE: ngOnInit will be fired once,
        // even If you use same component for different routes.
        // If You want to rebind data when You change route
        // You should not use snapshot but subscribe on
        // this.route.data or this.route.params eg.:
        this.route.params.subscribe((params: Params) => this.resource = params['resource']);
        this.route.data.subscribe((data: any) => this.team = data['team']);
    }
}

希望对您有所帮助,祝黑客愉快!

我遇到了完全相同的问题。

Route 的专用组件将包含泛型组件可能是解决方案。但这并不优雅,而是绕过而不是解决方案。