问题描述
我已经通过以下 SO 问题寻求解决方案:
Angular: 7.2.1 ES6 class ReferenceError : Cannot access 'X' before initialization
首先,我在 VS Code 终端上收到以下警告:
检测到循环依赖项中的警告: src\app\modules\asset-classes\fixed-income\fixed-deposits\components\fixed-deposits-details\fixed-deposits-details.component.ts -> src\app\modules\asset-classes\fixed-income\fixed-deposits\components\fixed-deposits-form\fixed-deposits-form.component.ts -> src\app\modules\asset-classes\fixed-income\fixed-deposits\components\fixed-deposits-details\fixed-deposits-details.component.ts
检测到循环依赖项中的警告: src\app\modules\asset-classes\fixed-income\fixed-deposits\components\fixed-deposits-form\fixed-deposits-form.component.ts -> src\app\modules\asset-classes\fixed-income\fixed-deposits\components\fixed-deposits-details\fixed-deposits-details.component.ts -> src\app\modules\asset-classes\fixed-income\fixed-deposits\components\fixed-deposits-form\fixed-deposits-form.component.ts
检测到循环依赖项中的警告: src\app\modules\shared\components\common-dialog\common-dialog.component.ts -> src\app\view-manager.service.ts -> src\app\modules\shared\components\common-dialog\common-dialog.component.ts
检测到循环依赖项中的警告: src\app\view-manager.service.ts -> src\app\modules\shared\components\common-dialog\common-dialog.component.ts -> src\app\view-manager.service.ts
现在,这显然是因为我各自组件中的以下代码:
fixed-deposits-form.component.ts
保存点击>>
this.viewService.loadSideNavWithCallback(
FixedDepositsDetailsComponent,(compRef: ComponentRef<any>) => {
compRef.instance.fixedDeposit = fixedDepositEntity;
});
fixed-deposits-details.component.ts
在编辑点击>>
this.viewService.loadSideNavWithCallback(
FixedDepositsFormComponent,(compRef: ComponentRef<any>) => {
compRef.instance.fixedDeposit = this.fixedDeposit;
});
viewService 基本上是我的 ViewManagerService,它有助于实现 Angular 组件之间的松散耦合,也用于视图导航。由于 FixedDepositsFormsComponent 和 FixedDepositsDetailsComponent 在侧导航(存在于 AppComponent 上)中打开,因此 ViewManagerService 负责加载这些组件。
此外,我在浏览器控制台中收到以下错误:
未捕获的引用错误:之前无法访问“FixedDeposit” 初始化 在 Module.FixedDeposit (main.js:4274) 在 Module../src/app/modules/asset-classes/fixed-income/fixed-deposits/components/fixed-deposits-details/fixed-deposits-details.component.ts (fixed-deposits-details.component.ts:21)
现在第 21 行只是指向我在 details 组件上的 @Input 属性:
export class FixedDepositsDetailsComponent implements OnInit {
@input() fixedDeposit: FixedDeposit;
如果我从我的 FixedDepositsFormComponent 中删除 loadSideNavWithCallback 代码(在保存点击时调用),就没有错误。但是我不能取消它,因为我需要使用该代码来加载详细信息组件。
提前感谢任何帮助。
解决方法
循环依赖是不好的,因为它使得 webpack 无法按照依赖顺序初始化模块。通常,webpack 会确保每当一个模块的导出在别处导入时,导出模块在导入模块之前执行,从而确保所有值在导入别处之前都已定义和初始化。
但是,如果存在循环依赖,则不存在这样的初始化顺序,从而有可能在定义之前导入值,causes the import to return undefined
。由于这令人惊讶且难以调试,因此如果检测到循环依赖项,Angular CLI emits 会发出警告。它做得很好,因为它暗示了您的 FixedDeposit
在初始化之前是如何被使用的。
因此,最好注意 CLI 的警告并避免在代码中创建循环依赖项。
viewService 基本上是我的 ViewManagerService,它有助于实现 Angular 组件之间的松散耦合,也用于视图导航
正如我们所见,您的“松散”耦合仍然太紧。此外,使用有状态导航服务绕过了 angular 路由器,使用户无法为单个视图添加书签,并导致开发过程中的实时重新加载回退到不同的视图。
出于所有这些原因,应该使用 angular 路由器而不是有状态的服务来执行导航。然后,组件可以在不知道负责该视图的组件的情况下导航到不同的视图,因此不会在组件类之间创建循环依赖关系。 in the official angular tutorial 提供了有关如何配置和使用 Angular 路由器的更多信息。
,为了避免循环依赖,我通常将操作代码(编辑/保存等)移动到公共服务中,并严格保持组件以 html 显示元素。即将 loadSideNavWithCallback 从 FixedDepositsFormComponent 移动到公共服务。
对我有用的一个很好的经验法则是避免将组件导入另一个组件/服务,而是使用服务。