问题描述
Angular项目中,父组件A下有一个子组件B,现在我把子组件B抽出来单独放在一个Module中。在B组件的构造器中,注入NzModalRef,constructor( private modal: NzModalRef, ) {},此时会报错
问题解答
这个错误表示 Angular 的依赖注入系统无法找到 NzModalRef
的提供者。NzModalRef
是 NG-ZORRO(一个基于 Angular 的 UI 组件库)中的一个服务,通常在打开模态窗口时由 NzModalService
提供。
如果你在组件的构造函数中直接注入 NzModalRef
,那么这个组件必须是作为模态窗口的内容被创建的。如果这个组件不是作为模态窗口的内容被创建的,那么 Angular 就无法找到 NzModalRef
的提供者,从而导致这个错误。
解决这个问题的方法是,只在作为模态窗口内容的组件中注入 NzModalRef
。如果你需要在其他地方使用 NzModalRef
,你可以考虑使用 NzModalService
来打开模态窗口,并传递所需的数据。
例如:
this.nzModalService.create({
nzContent: YourComponent,
nzComponentParams: {
// 你可以在这里传递参数到 YourComponent
},
});
然后在 YourComponent
中:
constructor(
private modal: NzModalRef,
) {
// 你可以在这里使用 this.modal 来访问 NzModalRef
}
报错场景描述
现在遇到的问题是 C组件是使用NzModalService 来打开模态窗口,这样是能打开的,但是A组件使用Iframe,使用url来打开B组件,会报错。
在这种情况下,问题的根源在于 NzModalRef
是由 NzModalService
在打开模态窗口时提供的。当你直接通过 URL 在 iframe 中加载 B 组件时,NzModalService
并没有被调用,因此 NzModalRef
没有被提供,导致了这个错误。
解决这个问题的一种方法是在 B 组件中使用可选的依赖注入来注入 NzModalRef
。这样,当 NzModalRef
不存在时,Angular 不会抛出错误,而是将其值设为 null
。
你可以这样修改 B 组件的构造函数:
constructor(
@Optional() private modal: NzModalRef,
) {}
然后在使用 this.modal
的地方,你需要先检查它是否存在:
if (this.modal) {
// 使用 this.modal
}
这样,当 B 组件作为模态窗口的内容被创建时,this.modal
将是 NzModalRef
的实例;当 B 组件直接通过 URL 被加载时,this.modal
将是 null
。
@Optional()应该在什么情况下使用?
@Optional()
是 Angular 的一个装饰器,它告诉 Angular 的依赖注入系统,如果找不到依赖,就将其值设为 null
,而不是抛出错误。
在你的情况中,当 B 组件作为模态窗口的内容被创建时,NzModalRef
是存在的,所以 this.modal
将是 NzModalRef
的实例;但是当 B 组件直接通过 URL 被加载时,NzModalRef
是不存在的,如果没有 @Optional()
,Angular 就会抛出错误。使用了 @Optional()
之后,Angular 就会将 this.modal
设为 null
,而不是抛出错误。
这样,你就可以在代码中检查 this.modal
是否存在,然后决定是否使用它。