如何在NgbModal中从延迟加载的模块中打开一个组件?

时间:2018-01-06 09:13:55

标签: angular typescript ng-bootstrap

我在尝试从延迟加载的模块加载动态组件时遇到问题。更准确地说,我试图在一个模态(https://ng-bootstrap.github.io/#/components/modal/examples)中打开登录组件,而不是在一个单独的页面中,同时保持单独的登录路由/页面完整。

现在,在我看来,我必须在app模块中急切加载登录组件,这只不过是一个临时的黑客。所以,我不想要这个解决方案。

我已尝试直接使用该组件,但正如我所料,它给了我以下错误:

找不到SigninComponent的组件工厂。你有没有把它添加到@ NgModule.entryComponents?

我搜索并找到了这个链接:https://github.com/angular/angular/issues/14324但无法使其正常工作。

我很惊讶我无法找到解决此问题的正确方法,因为这是一个非常常见的用例。任何帮助或建议表示赞赏。谢谢!

2 个答案:

答案 0 :(得分:1)

未通过其选择器直接在模板中使用的组件必须添加到entryComponents装饰器中的模块@NgModule数组中。在bootstrap中打开一个模态时,你实际上并没有在任何地方使用组件的选择器,所以你的SignInComponent就是这样一个例子。

你会做这样的事情

@NgModule({
    //...
    declarations: [
        SignInComponent,
    ],
    entryComponents: [
        SignInComponent,
    ]
})
export class LazyLoadedModule {
}

标记要编译的组件,即使它没有通过其选择器在任何其他组件的模板中引用。

您可以在官方角度文档here中阅读有关条目组件,它们如何工作以及为什么需要以这种方式声明它们的更多信息。和StackOverflow post一样。

答案 1 :(得分:0)

以下是我设法做你想做的事情。我的想法是,由于登录组件位于惰性模块中,因为路由器在导航到某些路由时会加载惰性模块,因此您需要在模式内导航到加载惰性模块并显示登录的路由零件。这可以使用命名的路由器插座来完成。我对命名的路由器插座不是很有经验,所以可能有一些东西需要改进,但它似乎有效。

因此,假设您有一个惰性模块LoginModule,其中一个空路径路由显示登录组件,以下是如何定义根模块的路由:

export const ROUTES: Routes = [
  {
    path: '',
    component: HomeComponent
  },
  {
    path: 'login', 
    loadChildren: './login/login.module#LoginModule'
  },
  { 
    path: 'modal-login',
    component: ModalLoginShellComponent, 
    outlet: 'modal', 
    children: [
       {
         path: '',
         loadChildren: './login/login.module#LoginModule'
       }
    ]
  }
];

home组件将有一个允许在模态内打开ModalLoginComponent的链接(如ng-bootstrap示例中所示)。此ModalLoginComponent模板如下所示:

<div class="modal-header">
  <h4 class="modal-title">Hi there!</h4>
  <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
    <span aria-hidden="true">&times;</span>
  </button>
</div>
<div class="modal-body">
  <router-outlet name="modal"></router-outlet>
</div>
<div class="modal-footer">
  <button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
</div>

重要的部分是

<router-outlet name="modal"></router-outlet>

它允许在模态内导航到路线,特别是导航到加载惰性模块的路线。

ModalLoginComponent的代码将具有以下ngOnInit(),它将触发导航:

ngOnInit() {
  this.router.navigate([{outlets: {'modal': ['modal-login']}}]);
}

这样就可以在模态体内加载ModalLoginShellComponent及其默认的延迟加载子路径。 ModalLoginShellComponent是一个无所事事的愚蠢组件,只是作为其模板

<router-outlet></router-outlet>