首页 > 解决方案 > 子组件引用父组件时出现 Angular NG3003 错误

问题描述

考虑以下情况:父组件在其模板中使用子组件,并且子组件具有对注入其中的父组件的引用。

父组件.html:

<child></child>

child.component.ts:

import { ParentComponent } from '../parent/parent.component.ts'

@Component({ 
  selector: 'child'
  ... 
})
export class ChildComponent {
  
  constructor(private parent: ParentComponent) { }
}

在使用推荐的部分编译模式编译的库中使用此设置时,编译器会引发NG3003 错误。Angular 文档提供了以下解决问题的想法:

  1. 尝试重新安排您的依赖关系以避免循环。例如,使用存储在独立文件中的中间接口,该文件可以导入到两个依赖文件中,而不会导致导入周期。

    • 在子组件中使用接口来引用父组件是不可能的,因为注入器不知道要注入什么。
  2. 将相互引用的类移动到同一个文件中,以避免它们之间的任何导入。

    • 我只是不想这样做。:)
  3. 如果导入的声明仅用作类型,则将导入语句转换为仅类型导入(使用导入类型语法),因为仅类型导入不会导致循环。

    • 与接口相同的问题,注入器不知道要注入什么。

是否有另一种方法可以解决 N3003 错误而不将父组件和子组件移动到同一个文件中?

标签: angularcircular-dependencyangular-libraryangular12angular-ivy

解决方案


上述情况下的 N3003 错误可以使用InjectionToken解决,如下所示:

  1. 创建注入令牌:

    parent.token.ts:

    export const PARENT = new InjectionToken('Parent Component');
    
  2. 将父组件分配给注入令牌:

    父组件.ts

    import { ParentComponent } from '../parent/parent.component.ts'
    
    @Component({ 
      ...
      provider:[{
        provide: PARENT,
        useExisting: ParentComponent 
      }]
    })
    export class ParentComponent { }
    
  3. 在子组件中,要求注入器注入注入令牌,并且仅按类型引用父组件:

    child.component.ts

    // Import ParentComponent as a type only.
    import type { ParentComponent } from '../parent/parent.component.ts';
    import { PARENT } from '../parent/parent.token.ts';
    
    @Component({ ... })
    export class ChildComponent {
    
      constructor(@Inject(PARENT) private parent: ParentComponent) { }
    }
    

推荐阅读