Angular 角度路由器:如何将数据传递到延迟加载模块?

Angular 角度路由器:如何将数据传递到延迟加载模块?,angular,lazy-loading,angular-routing,angular-module,angular-router,Angular,Lazy Loading,Angular Routing,Angular Module,Angular Router,我的Angular应用程序的模块有以下路由路径: @NgModule({ imports: [ RouterModule.forChild([ { path: 'documents', data: { myObject: MyConstants.OPTION_ONE }, children: [ {

我的Angular应用程序的模块有以下路由路径:

@NgModule({
    imports: [
        RouterModule.forChild([
            {
                path: 'documents',
                data: { myObject: MyConstants.OPTION_ONE },
                children: [
                    {
                        path: ':ID_DOC',
                        children: [
                            { path: 'edit', component: EditDocumentComponent },
                            { path: '', component: DocumentDetailsComponent },
                        ]
                    },
                    { path: 'add', component: AddDocumentComponent },
                    { path: '', component: DocumentsListComponent }
                ]
            }
        ])
    ],
    exports: [
        RouterModule
    ]
})

export class DocumentsManagementRoutingModule {
}
如您所见,我使用
data
属性将一些数据传递到“文档”中的每个路径,因此我可以从路由路径中声明的任何组件获取数据:

例如,以下是如何在
文档详细信息组件中获取数据:

export class DocumentDetailsComponent implements OnDestroy {
    private obsData: Subscription;
    private option: any;

    constructor(private route: ActivatedRoute) {
        this.obsData = this.route.data.subscribe(data => {
            this.option = data['myObject'];
        });
    }

    ngOnDestroy(): void {
        this.obsData.unsubscribe();
    }
}
现在,我更改了整个应用程序的路由结构,并使用
loadChildren
属性从其他模块调用上述模块。我以同样的方式传递数据:

@NgModule({
    imports: [
        RouterModule.forChild([
            {
                path: 'users',
                loadChildren: 'app/documents/documents.module#DocumentsModule',
                data: { myObject: MyConstants.OPTION_ONE }},
            {
                path: ':ID_USER',
                children: [
                    { path: 'edit', component: EditUserComponent },
                    { path: '', component: UserDetailsComponent },
                ]
            },
            { path: 'add', component: AddUserComponent },
            { path: '', component: UserListComponent }
        ])
    ],
    exports: [
        RouterModule
    ]
})

export class UsersManagementRoutingModule {
}
我对调用
DocumentsManagementRoutingModule
的所有其他模块也做了同样的操作,将
myObject
属性更改为
MyConstants.OPTION\u TWO
MyConstants.OPTION\u TWO
等等,根据我的需要


然后,由于我不知道调用延迟加载模块的模块及其相关路径,如何从调用方模块获取
数据
属性?

为什么不使用服务在模块或任何组件之间共享数据。您可以在主模块提供程序中导入此服务,因此可以在所有其他模块(延迟加载模块)中使用并共享数据


该服务可以具有设置和获取值的功能,因此您可以在服务中使用这些功能来获取所需的数据

我想我可以理解问题所在


问题 以下是提供的plunker@smartmouse的路由图

- home
  - shop
  - contact
    - map
  - about
home
路由配置上配置了一个
data
对象。直接子路由可以访问此数据对象。问题是,非直接子
map
希望访问
数据
对象,但显然不能

我们可以知道@smartmouse希望进一步推动--嵌套的非直接子路由可以访问来自祖先的数据

为什么不能呢? 看看我改装的普朗克

您可以看到,我为
contact
定义了一个额外的子组件
DefaultComponent
。它显示它是route
contact
的直接和默认子级,可以解释为它也是上级route
home
的直接子级。因此,它可以访问
数据
对象

解决方案 再看看我提供的弹夹

注意:我使用的Angular软件包是v4.3.0

方法#1——查询参数 我在
home.component.ts中为
contact
route定义了一些查询参数。你可以看看如何使用它

专业人士

  • 您可以跨任何级别的路由访问查询参数
  • 适用于lazyload模块
缺点

  • 无法在路由配置中定义查询参数

    但是您可以使用一些路由生命周期挂钩为目标祖先路由定义它们

方法2——服务 在应用程序的顶层定义一个数据共享服务,以单例模式运行。另外,使用一些util来防止它被启动两次。然后你可以把一些数据放进去,然后在任何地方检索

专业人士

  • 通过DI全球可见
  • 适用于lazyload模块
缺点

  • 无法在路由配置中更新数据
  • 您必须在其他地方定义数据。如果你不能控制它的来源,这可能是一个问题
方法#3——路线解析 有人可能会发现我还在plunker中定义了
resolve
示例代码。这表明它与route config中的
数据
具有相同的行为,只是它实际上用于动态数据检索


data属性用于将固定对象传递到激活的路由。它不会在应用程序的整个生命周期内更改。resolve属性用于动态数据

以@smartmouse的plunkr为例

我们在“主”路线配置中定义了
数据
。我们可以在
ContactModule
中为联系人的默认路由定义一个数据解析器,并代理从上级路由传递的数据。然后,其所有直接子路由都可以访问已解析的数据对象

专业人士

  • 适用于任何级别的嵌套管线
  • 适用于lazyload模块
缺点

  • 您可能必须在其子路由希望访问该数据的每个父路由中声明resolve属性。这是一种肮脏的工作


目前还没有完美且通用的解决方案,通常使用角度。有人应该权衡利弊,选择合适的路由。

您可以使用activatedRoute.pathFromRoot遍历父路由,并从最近的祖先那里获取可用的数据。类似的方法似乎奏效了:

  ngOnInit(): void {
    let idx = this.activatedRoute.pathFromRoot.length - 1;
    while(this.sharedData == null && idx > 0){
      this.sub = this.activatedRoute.pathFromRoot[idx].data.subscribe(subData => {

        if(subData.id)
          this.sharedData = subData;

        console.log('shared data', this.sharedData);
      });
      idx--;
    }
  }
@NgModule({
进口:[
RouterModule.forChild([
{
路径:“用户”,
loadChildren:'app/documents/documents.module#DocumentsModule',
决心:{
数据:数据解析程序
}
{
])
],
出口:[
路由模块
]
})
导出类UsersManagementRoutingModule{
}
@可注射()
导出类DataResolution实现解析{
解决(){
返回此.serice.getData();
}
}

在我的情况下,可能会重复使用延迟加载模块mandatory@smartmouse有一行
r.url.lastIndexOf(“/”))非法。在
UsersManagementRoutingModule
的routes配置的第一级中,有双路径用于
UsersManagementRoutingModule
如果我使用共享服务,则只有当您不通过直接url转到延迟加载模块时,它才会起作用。如果您转到属于延迟加载模块的页面,而不是通过pr发送数据的前一个模块
@NgModule({
    imports: [
        RouterModule.forChild([
            {
                path: 'users',
                loadChildren: 'app/documents/documents.module#DocumentsModule',
                resolve : {
                     data: DataResolver
                }
            {
        ])
    ],
    exports: [
        RouterModule
    ]
})

export class UsersManagementRoutingModule {
}


@Injectable()
export class DataResolverimplements Resolve<Data> {
  resolve() {
    return this.serice.getData();
  }
}