Angular router:如何将数据传递给延迟加载模块?

sma*_*use 17 lazy-loading angular-routing angular-module angular angular-router

我的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 {
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我使用dataproperty将一些数据传递给"documents"中的每个路径,因此我可以从路由路径中声明的任何组件中获取它:

例如,以下是我如何获取数据DocumentDetailsComponent:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我改变了整个应用程序的路由结构,并使用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 {
}
Run Code Online (Sandbox Code Playgroud)

而我做了所有调用其他模块一样DocumentsManagementRoutingModule,改变myObject属性MyConstants.OPTION_TWO,MyConstants.OPTION_THREE等等,根据我的需求.

然后,因为我不知道调用我的延迟加载模块的模块及其相关路径,如何data从调用模块获取属性?

e-c*_*oud 10

我想我可能会理解问题是什么.


问题

这是提供的plunker @smartmouse的路由图.

- home
  - shop
  - contact
    - map
  - about
Run Code Online (Sandbox Code Playgroud)

路由配置中data配置了一个对象home.直接子路由可以访问此数据对象.问题是,非直接孩子map想要访问该data对象,但显然,它不能.

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

为什么不能呢?

看到我修改过的那个弹药.https://plnkr.co/edit/FA7mGmspUXHhU8YvgDpT

您可以看到我DefaultComponent为其定义了一个额外的子组件contact.它表明它是路线的直接和默认子contact,可以解释为它也是上级路线的直接子home.因此,它可以访问该data对象.

再看看我提供的那个龙头.

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

方法#1 - 查询参数

home.component.tscontact路由定义了一些查询参数.你可以看到如何使用它.

优点:

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

缺点:

  • 你不能在路由配置中定义查询参数.

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

方法#2 - 服务

在作为Singleton Pattern播放的应用程序的顶层定义数据共享服务.另外,使用一些util来防止它被启动两次.然后你可以在其中放入一些数据,并在任何地方检索它.

优点:

  • 通过DI全局可见;
  • 适用于lazyload模块

缺点:

  • 您无法更新路由配置中的数据.
  • 你必须在别的地方定义数据.如果你无法控制它的来源,那可能是个问题.

方法#3 - 路线解决

有人可能会发现我还在resolveplunker中定义了示例代码.这表明它具有与data路由配置相同的行为,除了它实际上是用于动态数据检索.

https://vsavkin.com/angular-router-understanding-router-state-7b5b95a12eab#5400
data属性用于将固定对象传递给激活的路由.它在应用程序的整个生命周期内都不会改变.resolve属性用于动态数据.

以@ smartmouse的plunkr为例.

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

优点:

  • 适用于任何级别的嵌套路由
  • 适用于lazyload模块

缺点:

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

目前,没有完美和通用的解决方案,通常使用Angular.有人应权衡利弊,选择合适的利弊.


rus*_*mus 6

您可以使用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--;
    }
  }
Run Code Online (Sandbox Code Playgroud)

https://plnkr.co/edit/K5Rb1ZvTvSQNM6tOLeFp