子组件引用父组件时出现 Angular NG3003 错误

分享于2023年05月08日 angular angular-ivy angular-library angular12 circular-dependency 问答
【问题标题】:Angular NG3003 error when child component references parent component子组件引用父组件时出现 Angular NG3003 错误
【发布时间】:2023-05-07 06:34:01
【问题描述】:

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

parent.component.html:


child.component.ts:

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

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

在使用推荐的 partial compilation mode 编译的库中使用此设置时,编译器会抛出 NG3003 error 。 Angular 文档提供了以下解决问题的想法:

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

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

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

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

在不将父子组件移动到同一个文件的情况下,有没有其他方法可以解决N3003错误?


【解决方案1】:

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

  1. 创建注入令牌:

    parent.token.ts:

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

    parent.component.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) { }
    }
    

【讨论】: