Angular 2'组件'不是已知元素

Ara*_*nha 100 typescript angular-module angular-components angular

我正在尝试在其他模块中使用我在AppModule中创建的组件.我收到以下错误:

"未捕获(承诺):错误:模板解析错误:

'contacts-box'不是已知元素:

  1. 如果'contacts-box'是Angular组件,则验证它是否是此模块的一部分.
  2. 如果'contacts-box'是Web组件,则将'CUSTOM_ELEMENTS_SCHEMA'添加到此组件的'@NgModule.schemas'以禁止显示此消息.

我的项目结构很简单: 整体项目结构

我将页面保存在页面目录中,每个页面保存在不同的模块中(例如客户模块),每个模块都有多个组件(如customers-list-component,customers-add-component等).我想在这些组件中使用我的ContactBoxComponent(例如,在customers-add-component内部).

如您所见,我在widgets目录中创建了contacts-box组件,因此它基本上位于AppModule中.我将ContactBoxComponent导入添加到app.module.ts并将其放入AppModule的声明列表中.它没有用,所以我搜索了我的问题,并将ContactBoxComponent添加到导出列表中.没有帮助.我也尝试将ContactBoxComponent放在CustomersAddComponent中,然后放在另一个(来自不同的模块)中,但我得到一个错误,说有多个声明.

我错过了什么?

Rob*_*hof 212

这是我遇到这样的错误时执行的5个步骤.

  • 你确定这个名字是对的吗?(还要检查组件中定义的选择器)
  • 在模块中声明组件?
  • 如果它在另一个模块中,导出组件?
  • 如果它在另一个模块中,导入该模块?
  • 重启cli?

我也尝试将ContactBoxComponent放在CustomersAddComponent中,然后放在另一个(来自不同的模块)中,但我得到一个错误,说有多个声明.

您不能两次声明组件.您应该在新的sepperate模块中声明和导出组件.接下来,您应该在要使用组件的每个模块中导入此新模块.

很难说你什么时候应该创建新模块,什么时候不应该.我通常会为我重用的每个组件创建一个新模块.当我有一些我几乎在任何地方使用的组件时,我将它们放在一个模块中.当我有一个我不重用的组件时,我不会创建一个单独的模块,直到我需要它在其他地方.

虽然将所有组件放在一个模块中可能很诱人,但这对于性能来说是不好的.在开发时,模块必须在每次更改时重新编译.模块越大(组件越多),花费的时间就越多.对大模块进行小的更改比在小模块中进行小的更改需要更多的时间.

  • 您应该在一个单独的模块中声明和导出您的组件,而不是在AppModule中.接下来,您应该在每个模块中导入这个新模块以使用您的组件. (7认同)
  • 那是对的.很难说你何时应该创建新模块,什么时候不应该创建新模块.我通常会为我重用的每个组件创建一个新模块.当我有一些我几乎在任何地方使用的组件时,我将它们放在一个模块中.当我有一个我不重用的组件时,我不会创建一个单独的模块,直到我需要它在其他地方. (5认同)
  • 你的步骤对我没有帮助,但也许是因为我对Angular 2很新,所以我会回答它们,也许我们会一起解决这个问题.我确定名称是正确的,我在AppModule中声明了组件,我在AppModule中导出了组件并重新启动了cli.我也尝试在我的CustomersAddComponent中导入AppModule,但是它导致错误:超出了最大调用堆栈大小(我想我们不会在Angular 2中导入AppModule). (4认同)
  • “重新启动 cli”对我有用。我不知道为什么会这样。 (4认同)
  • 好的,我现在明白了.唯一的问题是:当我导入新创建的模块(比如WidgetsModule)时,它会加载aaaaaall内部声明的组件,对吗?这是一些开销,但也许我误解了一些东西.我当然可以创建ContactsBoxModule,但这对于一个小组件来说就是很多.任何提示? (2认同)

Jan*_*ich 17

我有类似的问题.事实证明ng generate component(使用CLI版本7.1.4)将子组件的声明添加到AppModule,但不是模拟它的TestBed模块.

"英雄之旅"示例应用程序包含一个HeroesComponent带选择器app-heroes.应用程序运行正常,但ng test产生此错误消息:'app-heroes' is not a known element.HeroesComponent手动添加到configureTestingModule(in app.component.spec.ts)中的声明可消除此错误.

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent,
        HeroesComponent
      ],
    }).compileComponents();
  }));

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  });
}
Run Code Online (Sandbox Code Playgroud)


har*_*rci 13

我刚才有同样的问题.尝试一些张贴在这里的解决方案之前,你可能要检查如果组件真的不起作用.对我来说,错误显示在我的IDE(WebStorm)中,但事实证明,当我在浏览器中运行它时,代码运行得很好.

关闭终端(运行ng服务器)重新启动IDE后,消息停止显示.

  • 我在使用 VS Code 时遇到了同样的问题,但使用了 Ionic 2。在一个页面中它可以工作。在组件中存在错误 **ion-* is not a known element**。我已经尝试过你的建议来停止 **ionic serve** 并重新启动 IDE,但没有任何效果。你知道另一个解决方案吗?顺便说一句 - 代码无论如何都可以工作。 (2认同)

小智 10

很多答案/评论都提到了在其他模块中定义的组件,或者您必须在其/它们的包含模块中导入/声明组件(您想在另一个组件中使用)。

但是在简单的情况下,当两个A组件B都定义在同一个模块中时,您想要使用来自组件的组件,您必须在包含模块中声明两个组件 for Bto see A,而不仅仅是A.

即在 my-module.module.ts

import { AComponent } from "./A/A.component";
import { BComponent } from "./B/B.component";

@NgModule({
  declarations: [
    AComponent,   // This is the one that we naturally think of adding ..
    BComponent,   // .. but forget this one and you get a "**'AComponent'** 
                  // is not a known element" error.
  ],
})
Run Code Online (Sandbox Code Playgroud)


小智 9

我在 Angular CLI 中遇到了同样的问题:10.1.5 代码工作正常,但错误显示在 VScode v1.50

通过终止终端(ngserve) 并重新启动 VScode来解决。


P.M*_*P.M 5

这个问题可能看起来很老很奇怪,但是当我尝试加载模块(延迟加载)并得到相同的错误时,我意识到我缺少作为较大模块的一部分提供的组件的导出子句。

Angular.io 链接解释了原因:模块内的组件/服务默认情况下保持私有(或受保护)。要公开它们,您必须导出它们。

使用@live-love 代码示例扩展@Robin Djikof 的答案,这就是我的案例(Angular 8)中技术上缺少的内容:

@NgModule({
  declarations: [
    SomeOtherComponent,
    ProductListComponent
  ],
  imports: [
    DependantModule
  ],
  exports: [ProductListComponent] 
  //<- This line makes ProductListComponent available outside the module, 
  //while keeping SomeOtherComponent private to the module
})
export class SomeLargeModule { }
Run Code Online (Sandbox Code Playgroud)