Angular 懒加载动态组件

14
使用Angular 4.1.3,我正在开发一个地图应用程序,其中懒加载各种工具模块。目前,有一个路由出口,将工具放置在地图中。但是,我需要支持将工具放置在新标签页中,靠近地图。该选项卡是动态创建的,响应加载工具模块,并且可以同时打开多个选项卡。
创建选项卡组件非常简单,似乎在新选项卡中放置动态组件加载器(https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html)是一种合理的方法来放置工具在选项卡中。然而,我不知道如何实际获取对工具组件的引用,以将其传递给加载器,因为它是懒加载模块的一部分。是否有一种方法让路由器将其传递给我的app.component而不是通过router-outlet输出它?我考虑过将路由器出口放在隐藏的div中,然后在控制器中绑定到它,但那似乎很麻烦,而且我不确定它是否有效。
我看到了一些类似的问题/答案似乎依赖于SystemJS,但我正在使用Webpack。

编辑:我在这里运行了一个基本的 plunker:http://plnkr.co/edit/RPbyQZ4LyHN9o9ey2MJT?p=preview

那里的代码有一个非常基本的组件动态添加到一个选项卡中

  export class ContentPaneComponent implements OnInit {
  @ViewChild('contentpane') el: ElementRef;

  @Output() newContent: EventEmitter<any> = new EventEmitter();

  private content: string;
  private contentSubscription: Subscription;

  private tab1 = new CompItem(htmlPaneComponent, {});
  // private tab2 = new CompItem(LayerManagerComponent, {});

  ngOnInit(): void {
  }

}

在content-pane.module的entryComponents中必须包含在tab1中指定的组件:entryComponents: [htmlPaneComponent]

最终,我希望在惰性加载模块时创建新的CompItem()。当我激活一个路由时,例如:

{
    path: 'search', loadChildren:
    'components/conference-room-search/conference-room-search.module#ConferenceRoomSearchModule'
        }

我认为我需要的是路由器给我模块或其组件的引用。

你能否创建一个最简单的示例来展示你想要实现的内容? - yurzui
好的,我终于做了一个非常基本的plunker来演示我所描述的部分内容,网址是http://plnkr.co/edit/RPbyQZ4LyHN9o9ey2MJT?p=preview。这基本上是将此处显示的动态组件加载器:https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html和这里的选项卡实现结合起来:https://embed.plnkr.co/afhLA8wHw9LRnzwwTT3M/。 - Charlie Elverson
你是在询问如何获取对刚刚作为模块(即ConferenceRoomSearchModule)的一部分动态加载的组件的引用,以便您可以将其与动态组件加载器一起使用吗? - Daniel W Strimpel
我还想听一些动态创建组件的建议,并且在需要动态创建时懒惰地推迟加载组件的代码。 - Alexander Taylor
1个回答

3

这是一种动态和惰性加载组件的策略。但请注意,我还没有尝试过!

通过依赖注入获取一个NgModuleFactoryLoader实例,并异步获取包含要惰性加载的组件的模块。从中获取一个NgModuleFactory,然后获取一个NgModuleRef

NgModuleRef将为您提供:

  • 一个ComponentFactoryResolver,它接受Type<T>(来自@angular/core
  • 该模块类的instance()

所以你不能从你的代码中创建一个Type<T>并传递给ComponentFactoryResolver,因为你的代码不能依赖于T,但是模块可以访问T并提供一个Type<T>

使模块实现一个接口,该接口可以返回Type<any>(即组件类),并将NgModuleRef.instance()强制转换为该接口。然后使用ComponentFactoryResolver。如果由于某些原因不起作用,则使模块调用ComponentFactoryResolver并直接返回组件而不是Type。一旦你有了一个ComponentFactory,就可以像通常那样进行动态组件加载。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接