【问题标题】:Angular 2 'component' is not a known elementAngular 2“组件”不是已知元素
【发布时间】:2017-11-09 19:56:27
【问题描述】:

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

“未捕获(在承诺中):错误:模板解析错误:

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

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

我的项目结构很简单:

我将我的页面保存在 pages 目录中,其中每个页面保存在不同的模块中(例如 customers-module),并且每个模块都有多个组件(例如 customers-list-component、customers-add-component 等)。我想在这些组件中使用我的 ContactBoxComponent(例如在客户添加组件中)。

如您所见,我在小部件目录中创建了联系人框组件,因此它基本上位于 AppModule 中。我将 ContactBoxComponent 导入添加到 app.module.ts 并将其放入 AppModule 的声明列表中。它没有用,所以我搜索了我的问题并将 ContactBoxComponent 添加到导出列表中。没有帮助。我还尝试将 ContactBoxComponent 放入 CustomersAddComponent 中,然后放入另一个中(来自不同的模块),但我收到一条错误消息,提示有多个声明。

我错过了什么?

【问题讨论】:

  • 您的文件夹结构并不简单。这很令人困惑。我建议遵循 Angular Style Guide(链接未提供 b/c 他们更改)并使用他们的文件夹结构建议,然后确保您正确使用模块。这就是这个意思。您在某些时候没有在应用程序摄取的模块中导出或声明您的组件。
  • 我遇到了这个问题并通过包含一个组件来解决它,该组件未包含但有一个组件包含它。重点是......我阅读了以下所有答案并尝试了很多东西,然后才找到我的解决方案......所有好的贡献,所以建议阅读不止一个。 HTH
  • 如果所有答案都不起作用,请删除并重新创建“联系人框”组件。

标签: angular typescript angular-components angular-module


【解决方案1】:

这些是我遇到此类错误时执行的 5 个步骤。

  • 您确定名称正确吗? (还要检查组件中定义的选择器)
  • 在模块中声明组件?
  • 如果在其他模块,导出组件?
  • 如果它在另一个模块中,导入那个模块?
  • 重启 cli?

在单元测试过程中发生错误时,请确保您在TestBed.configureTestingModule中声明了组件或导入了模块

我还尝试将 ContactBoxComponent 放入 CustomersAddComponent 中,然后放入另一个(来自不同的模块),但我收到一个错误,提示有多个声明。

您不能两次声明一个组件。您应该在一个新的单独模块中声明和导出您的组件。接下来,您应该在要使用组件的每个模块中导入这个新模块。

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

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

【讨论】:

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

我刚刚遇到了完全相同的问题。在尝试此处发布的一些解决方案之前,您可能需要检查组件是否真的 不起作用。对我来说,错误显示在我的 IDE (WebStorm) 中,但事实证明,当我在浏览器中运行代码时,代码运行良好。

在我关闭终端(正在运行 ng serve)重新启动我的 IDE 后,消息停止显示。

【讨论】:

  • 问题是特定于 ide 的。我对 webstorm 有同样的问题。使用 angular-cli 所做的更改不会通知 Webstorm,因此您必须重新启动 IDE 以使其“看到”任何新组件!
  • 我对 VS Code 也有同样的问题,但使用 Ionic 2。在一个页面中它可以工作。在组件中存在错误ion-* is not a known element。我已尝试您的建议停止 ionic serve 并重新启动 IDE,但没有任何效果。你知道这个的另一种解决方案吗?顺便说一句 - 代码仍然有效。
  • VSCode 有同样的问题。重新启动编辑器后,消息消失了。
【解决方案3】:

我有相同的问题宽度 php Storm 版本 2017.3。这为我修复它: intellij support forum

这是一个错误宽度@angular 语言服务: https://www.npmjs.com/package/@angular/language-service

【讨论】:

  • 这也为 webstorm 2018.3 修复了它
【解决方案4】:

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

“英雄之旅”示例应用包含一个 HeroesComponent 和选择器 app-heroes。该应用程序在服务时运行良好,但ng test 产生了此错误消息:'app-heroes' is not a known element。将HeroesComponent 手动添加到configureTestingModule(在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();
  });
}

【讨论】:

    【解决方案5】:

    我遇到了同样的问题,这是因为不同的功能模块错误地包含了这个组件。当从其他功能中删除它时,它起作用了!

    【讨论】:

      【解决方案6】:

      我的问题是模块中缺少组件声明,但即使在添加声明之后,错误仍然存​​在。我已停止服务器并在 VS Code 中重建整个项目,以使错误消失。

      【讨论】:

        【解决方案7】:

        在我的例子中,我的应用有多个模块层,所以我尝试导入的模块必须添加到实际使用它的模块父级pages.module.ts,而不是app.module.ts

        【讨论】:

          【解决方案8】:

          这个复杂的框架让我发疯。鉴于您在 SAME 模块的另一个组件部分的模板中定义了自定义组件,那么您不需要在模块中使用导出(例如 app.module.ts)。您只需要在上述模块的@NgModule 指令中指定声明即可:

          // app.module.ts
          
          import { JsonInputComponent } from './json-input/json-input.component';
          
          @NgModule({
            declarations: [
              AppComponent,
              JsonInputComponent
            ],
            ...
          

          您无需将JsonInputComponent(在此示例中)导入AppComponent(在此示例中)即可在AppComponent 模板中使用JsonInputComponent 自定义组件。您只需在自定义组件前面加上已定义两个组件的模块名称(例如 app):

          <form [formGroup]="reactiveForm">
            <app-json-input formControlName="result"></app-json-input>
          </form>
          

          注意 app-json-input 不是 json-input!

          在这里演示:https://github.com/lovefamilychildrenhappiness/AngularCustomComponentValidation

          【讨论】:

            【解决方案9】:

            我开始使用 Angular,就我而言,问题是我在添加“import”语句后没有保存文件。

            【讨论】:

              【解决方案10】:

              路由模块(没有将此视为答案)

              首先检查: 如果您已在其模块中声明并导出组件,则将模块导入您要使用的位置并正确命名组件在 HTML 中。

              否则,您可能会错过路由模块中的某个模块:
              当您的路由模块具有从另一个模块路由到组件的路由时,在该路由模块中导入该模块很重要。否则 Angular CLI 将显示错误:component is not a known element

              例如

              1) 具有以下项目结构:

              ├───core
              │   └───sidebar
              │           sidebar.component.ts
              │           sidebar.module.ts
              │
              └───todos
                  │   todos-routing.module.ts
                  │   todos.module.ts
                  │
                  └───pages
                          edit-todo.component.ts
                          edit-todo.module.ts
              

              2) 在todos-routing.module.ts 中,您有一条到edit.todo.component.ts 的路由(不导入其模块):

                {
                  path: 'edit-todo/:todoId',
                  component: EditTodoComponent,
                },
              

              这条路线可以正常工作!但是,当在edit-todo.module.ts 中导入sidebar.module.ts 时,您会收到错误:app-sidebar is not a known element

              修复:由于您在步骤 2 中添加了到 edit-todo.component.ts 的路由,因此您必须将 edit-todo.module.ts 添加为导入,之后导入的侧边栏组件将起作用!

              【讨论】:

                【解决方案11】:

                我遇到了同样的问题。就我而言,我忘记在 app.module.ts

                例如,如果您在ToDayComponent 模板中使用&lt;app-datapicker&gt; 选择器,则应在app.module.ts

                中同时声明ToDayComponentDatepickerComponent

                【讨论】:

                  【解决方案12】:

                  假设你有一个组件:

                  产品列表.component.ts:

                  import { Component } from '@angular/core';
                      
                      @Component({
                          selector: 'pm-products',  
                          templateUrl: './product-list.component.html'
                      })
                      
                      
                      export class ProductListComponent {
                        pageTitle: string = 'product list';
                      }
                  

                  你得到这个错误:

                  src/app/app.component.ts:6:3 中的错误 - 错误 NG8001: 'pm-products' 不是已知元素:

                  1. 如果“pm-products”是一个 Angular 组件,则验证它是否是该模块的一部分。

                  app.component.ts:

                  import { Component } from "@angular/core";
                  @Component({
                    selector: 'pm-root', // 'pm-root'
                    template: `
                    <div><h1>{{pageTitle}}</h1>
                    <pm-products></pm-products> // not a known element ?
                    </div>
                    `
                  })
                  export class AppComponent {
                    pageTitle: string = 'Acme Product Management';
                  }
                  

                  确保导入组件:

                  app.module.ts:
                  
                  import { BrowserModule } from '@angular/platform-browser';
                  import { NgModule } from '@angular/core';
                  
                  import { AppComponent } from './app.component';
                  
                  // --> add this import (you can click on the light bulb in the squiggly line in VS Code)
                  import { ProductListComponent } from './products/product-list.component'; 
                  
                  @NgModule({
                    declarations: [
                      AppComponent,
                      ProductListComponent // --> Add this line here
                  
                    ],
                    imports: [
                      BrowserModule
                    ],
                    bootstrap: [AppComponent],
                  
                  
                  })
                  export class AppModule { }
                  

                  【讨论】:

                    【解决方案13】:

                    这个问题可能看起来很老很奇怪,但是当我尝试加载一个模块(延迟加载)并遇到同样的错误时,我意识到我错过了一个 exports 组件的子句作为更大模块的一部分。

                    这个Angular.io Link explains why:模块内的组件/服务,默认情况下保持私有(或受保护)。要将它们公开,您必须将它们导出。

                    @live-love code sample 扩展@Robin Djikof's answer,这是我的案例(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 { }
                    

                    【讨论】:

                      【解决方案14】:

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

                      但是在简单的情况下,如果您想使用组件 B 中的组件 A,当两者都定义在同一个模块中时,您必须在包含模块中为 @ 声明 both 组件987654323@查看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.
                        ],
                      })
                      

                      【讨论】:

                        【解决方案15】:

                        我在使用 Angular CLI 时遇到了同样的问题:10.1.5 代码工作正常,但 VScode v1.50

                        中显示错误

                        通过杀死终端(ng serve)和重启VScode解决。

                        【讨论】:

                          【解决方案16】:

                          我知道这是一个长期解决的问题,但就我而言,我有不同的解决方案。 这实际上是我犯的一个错误,也许你也犯了,但没有完全注意到。我的错误是我不小心在声明部分放置了一个模块,例如 MatChipsModule、MatAutoCompleteModule;仅由组件组成的部分,例如 MainComponent、AboutComponent。这使我的所有其他导入都无法识别。

                          【讨论】:

                            【解决方案17】:

                            我花了半天时间来解决这个问题。问题在于进口。我的 HomeModule 有 homeComponent ,它包含在 html 中。 ProductComponent 是 ProductModule 的一部分。我在 HomeModule 的导入中添加了 ProductModule,但忘记在 AppModule 的导入中添加 HomeModule。添加后,问题消失了

                            【讨论】:

                              【解决方案18】:

                              在执行 Angular 的 Getting Started Tutorial 时,我在使用 Angular Generator 通过工具 stackblitz.com 生成一个名为 product-alerts 的新组件后也收到此错误。

                              'app-product-alerts' is not a known element:

                              发现:其他人在 2021 年 8 月上旬也遇到过这种情况。目前,这似乎是 StackBlitz IDE 中的一个错误。 https://github.com/angular/angular/issues/43020

                              【讨论】:

                                【解决方案19】:

                                有时甚至只是重新启动你的 IDE 就可以了!!? 遇到同样的问题,重启 VS Code 解决了

                                【讨论】:

                                • 谢谢。我希望人们在进入其他兔子洞之前尝试一下。
                                【解决方案20】:

                                我的情况有点不同。我收到此错误消息,但这是因为我的 pages 模块没有我生成的新页面。

                                我的步骤:

                                1. 生成新的页面组件
                                2. 将现有组件导入新页面的 module.ts 文件中
                                3. 在新页面的 HTML 文件中使用 &lt;myapp-header&gt;&lt;/myapp-header&gt; 组件选择器

                                得到错误并卡在这里。对我来说最后一步是:

                                1. 将新页面模块导入pages.module.ts 文件。

                                现在它可以按预期工作了。这次错误消息并没有太大帮助。

                                【讨论】:

                                  【解决方案21】:

                                  对于我的应用模式,一旦我在 app.module.ts 文件中声明了我的 LandingPageComponent,将子模块导入其中就可以了。

                                  我刚刚开始了一个新项目,并认为其中一些模式是理所当然的。

                                  【讨论】:

                                    猜你喜欢
                                    • 1970-01-01
                                    • 2021-09-16
                                    • 1970-01-01
                                    • 2017-11-14
                                    • 1970-01-01
                                    • 2017-07-26
                                    • 2017-01-20
                                    • 1970-01-01
                                    • 2019-06-27
                                    相关资源
                                    最近更新 更多