Angular 2'component'不是一个已知元素


134

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

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

“联系人框”不是已知元素:

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

我的项目结构非常简单: 总体项目结构

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

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

我想念什么?


您的文件夹结构并不简单。令人困惑。我建议遵循《 Angular样式指南》(未更改链接提供b / c)并使用其文件夹结构建议,然后确保正确使用模块。这就是这个意思。您有时不会在应用程序提取的模块中导出或声明您的组件。
约书亚·迈克尔·瓦格纳

Answers:


277

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

  • 您确定名称正确吗?(还要检查组件中定义的选择器)
  • 声明模块中的组件?
  • 如果在另一个模块中,是否导出组件?
  • 如果在另一个模块中,请导入该模块?
  • 重新启动CLI?

我还尝试将ContactBoxComponent放入CustomersAddComponent,然后放入另一个(来自不同模块),但出现错误,提示存在多个声明。

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

很难确定何时应该创建新模块,何时不应该创建新模块。我通常为我重用的每个组件创建一个新模块。当我拥有一些几乎可以在所有地方使用的组件时,我会将它们放在一个模块中。当我有一个不重复使用的组件时,除非需要其他地方,否则不会创建单独的模块。

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


6
您的步骤对我没有帮助,但也许是因为我对Angular 2还是很陌生,所以我会回答它们,也许我们会一起解决该问题。我确定名称正确,我在AppModule中声明了该组件,在AppModule中导出了该组件,然后重新启动了cli。我也尝试在我的CustomersAddComponent中导入AppModule,但导致错误:超出了最大调用堆栈大小(我想我们没有在Angular 2中导入AppModule)。
Aranha

7
您应该在单独的模块(而不是AppModule中)中声明和导出组件。接下来,您应该将此新模块导入您拥有的每个模块中以使用您的组件。
罗宾·迪克霍夫

2
好吧,我明白了。唯一的问题是:当我导入新创建的模块(例如WidgetsModule)时,它将加载里面声明的所有组件,对吗?那是一些开销,但也许我误会了一些东西。我当然可以创建ContactsBoxModule,但是对于一个小组件来说就足够了。有什么提示吗?
Aranha

5
没错 而且很难告诉您何时应该创建新模块,何时不应该创建新模块。我通常为我重用的每个组件创建一个新模块。当我拥有一些几乎可以在所有地方使用的组件时,我会将它们放在一个模块中。当我有一个不重复使用的组件时,除非需要其他地方,否则不会创建单独的模块。
罗宾·迪克霍夫

2
“如果在另一个模块中,是否导出组件?” 为我工作!
史蒂文

25

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

“英雄之旅”示例应用程序包含一个HeroesComponentwith选择器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();
  });
}

这是我的问题-忘记在测试文件中添加导入。
Sellorio

17

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

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


该问题是特定于ide的。我对webstorm有同样的问题。Webstorm不会通知您有关angular-cli所做的更改,因此您必须重新启动IDE以使其“看到”任何新组件!
skiabox

2
我对VS Code有相同的问题,但对Ionic 2却有同样的问题。在页面中它可以工作。在组件中存在错误ion- *不是已知元素。我已经尝试了您的建议以停止离子服务并重新启动IDE,但是没有任何效果。您知道其他解决方案吗?顺便说一句-该代码仍然有效。
塞巴斯蒂安·奥尔特曼

VSCode也有同样的问题。重新启动编辑器后,消息消失了。
quicklikerabbit


1

就我而言,我的应用程序具有多层模块,因此我要导入的模块必须添加到实际使用该模块的父模块中pages.module.ts,而不是app.module.ts



0

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


0

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

// app.module.ts

import { JsonInputComponent } from './json-input/json-input.component';

@NgModule({
  declarations: [
    AppComponent,
    JsonInputComponent
  ],
  ...

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

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

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

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


0

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


0

路由模块(未将其视为答案)

首先检查: 如果已在组件的内部声明并导出了组件,则将模块导入要使用的模块,并在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,
  },

该路线将正常工作!但是,在导入sidebar.module.ts内部时,edit-todo.module.ts您将得到一个错误:app-sidebar is not a known element

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


0

我面临着同样的问题。就我而言,我忘记了在 app.module.ts中

作为一个例子,如果你使用的是<app-datapicker>在选择ToDayComponent模板,你应该同时声明ToDayComponent,并DatepickerComponentapp.module.ts


0

假设您有一个组件:

product-list.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 { }

0

这个问题看似古老而奇怪,但是当我尝试加载模块(延迟加载)并遇到相同的错误时,我意识到我缺少作为较大模块的一部分运输的组件exports子句

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

@ live-love代码示例扩展@Robin Djikof的答案,这是我的情况(角度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 { }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.