Angular2 RC6: '<компонент> не является известным элементом'

128

Я получаю следующую ошибку в консоли браузера при попытке запустить приложение Angular 2 RC6:

> Error: Template parse errors: 'header-area' is not a known element:
> 1. If 'header-area' is an Angular component, then verify that it is part of this module.
> 2. If 'header-area' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schema' of this component
> to suppress this message.("

    <div class="page-container">
        [ERROR->]<header-area></header-area>
        <div class="container-fluid">

> "): PlannerComponent@1:2

Я не понимаю, почему компонент не найден. Мой PlannerModule выглядит так:

@NgModule({
  declarations: [
    PlannerComponent,
    HeaderAreaComponent,
    NavbarAreaComponent,
    EreignisbarAreaComponent,
    GraphAreaComponent,
    nvD3
    ],
  imports: [
    RouterModule,
    CommonModule,
    ModalModule
    ],
  bootstrap: [PlannerComponent],
})
export class PlannerModule {}

и насколько я понял концепцию модулей в ng2, части модулей объявлены в «объявлениях». Для полноты, вот PlannerComponent:

@Component({
  selector: 'planner',
  providers: [CalculationService],
  templateUrl: './planner.component.html',
  styleUrls: ['./planner.component.styl']
})
export default class PlannerComponent {
}

и HeaderAreaComponent:

@Component({
  selector: 'header-area',
  templateUrl: './header-area.component.html',
  styleUrls: ['./header-area.component.styl']
})
export default class HeaderAreaComponent {
}

<header-area>-Tag расположен в planner.component.html:

<div class="page-container">
  <header-area></header-area>
  <div class="container-fluid">

    <div class="row">...

Я что-то не так понял?

Обновление : полный код

planner.module.ts:

import HeaderAreaComponent from '../header-area/header-area.component';
import NavbarAreaComponent from '../navbar-area/navbar-area.component';
import GraphAreaComponent from '../graph-area/graph-area.component';
import EreignisbarAreaComponent from '../ereignisbar-area/ereignisbar-area.component';
import PlannerComponent from './planner.component';
import {NgModule} from '@angular/core';
import {nvD3} from 'ng2-nvd3';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {ModalModule} from 'ng2-bootstrap/ng2-bootstrap';

@NgModule({
  declarations: [
    PlannerComponent,
    HeaderAreaComponent,
    NavbarAreaComponent,
    EreignisbarAreaComponent,
    GraphAreaComponent,
    nvD3
  ],
  imports: [
    RouterModule,
    CommonModule,
    ModalModule
  ],
  bootstrap: [PlannerComponent],
})
export class PlannerModule {
  // TODO: get rid of the "unused class" warning
}

planner.component.ts

import {Component} from '@angular/core';
import CalculationService from '../_shared/services/calculation.service/calculation.service';
import HeaderAreaComponent from '../header-area/header-area.component';

@Component({
  selector: 'planner',
  providers: [CalculationService],
  templateUrl: './planner.component.html',
  styleUrls: ['./planner.component.styl']
})
export default class PlannerComponent {
}

planner.component.html

<div class="page-container">
  <header-area></header-area>
  <div class="container-fluid">

    <div class="row">
      <div class="col-xs-2 col-sm-1 sidebar">
        <navbar-area></navbar-area>
      </div>
      <div class="col-xs-10 col-sm-11">
        <graph-area></graph-area>
      </div>
    </div><!--/.row-->

    <div class="row">
      <div class="col-xs-10 col-sm-11 offset-sm-1">
        <ereignisbar-area></ereignisbar-area>
      </div>
    </div><!--/.row-->

  </div><!--/.container-->
</div><!--/.page-container-->
frot.io
источник
1
Почему вы импортируете HeaderAreaComponentбез, {}а остальные с {}. Можете попробовать импортировать их таким же образом? (возможно, удаление default?)
Гюнтер Цохбауэр
Я удалил значение по умолчанию и импортировал без него {}, но получил тот же результат.
frot.io 05

Ответы:

252

Я получил эту ошибку, когда импортировал модуль A в модуль B, а затем попытался использовать компонент из модуля A в модуле B.

Решение состоит в том, чтобы объявить этот компонент в exportsмассиве.

@NgModule({
  declarations: [
    MyComponent
  ],
  exports: [
    MyComponent
  ]
})
export class ModuleA {}
@NgModule({
  imports: [
    ModuleA
  ]
})
export class ModuleB {}
Стивен Пол
источник
52
И, естественно, в документации по компонентам Angular об этом даже не упоминается.
Джон
Я целый день ломал голову над этим! Спасибо вам большое!
EGC
34

Я исправил это с помощью ответа Санкета и комментариев.

То, что вы не могли знать и не было очевидно в сообщении об ошибке: я импортировал PlannerComponent как @ NgModule.declaration в свой модуль приложения (= RootModule).

Ошибка была исправлена ​​путем импорта PlannerModule как @ NgModule.imports .

Перед:

@NgModule({
  declarations: [
    AppComponent,
    PlannerComponent,
    ProfilAreaComponent,
    HeaderAreaComponent,
    NavbarAreaComponent,
    GraphAreaComponent,
    EreignisbarAreaComponent
  ],
  imports: [
    BrowserModule,
    RouterModule.forRoot(routeConfig),
    PlannerModule
  ],
  bootstrap: [AppComponent]
})
export class AppModule {

После:

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    RouterModule.forRoot(routeConfig),
    PlannerModule
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
}

Спасибо за вашу помощь :)

frot.io
источник
1
Я отредактировал ваш ответ, чтобы изменить форматирование, чтобы разница была яснее. Теперь, когда я это сделал, я вижу, что разница в том, что вы просто удалили несколько элементов из declarations. Может ли это быть правильно?
Джейсон Светт
1
Джепп, верно. AppModule и PlannerModule - это две разные вещи, и я объявил некоторые компоненты в обоих. Он работает, объявляя компонент только в одном модуле и импортируя этот модуль в другой.
frot.io 05
спасибо за размещение вашего решения, но в разделе «до» вы также показываете как импортированный модуль PlannerModule
Хуан Монсальве
23

Если вы использовали автоматически сгенерированное определение компонента Webclipse, вы можете обнаружить, что к имени селектора добавлено «app-». По-видимому, это новое соглашение при объявлении подкомпонентов основного компонента приложения. Проверьте, как ваш селектор был определен в вашем компоненте, если вы использовали «новый» - «компонент» для его создания в Angular IDE. Поэтому вместо того, чтобы ставить

<header-area></header-area>

Вам может понадобиться

<app-header-area></app-header-area>
FayeB
источник
1
То же самое и с компонентами, созданными с помощью ngcli.
исследователь
Если я создаю компонент с --selectorопцией, мне не нужно добавлять префикс app-компонента. Пример:ng generate component menu-list --selector 'menu-list'
explorer
Не могу поверить, что это была моя проблема ..: / Спасибо! Upvoted !!
Саксофонист
8

Я получаю ту же проблему <flash-messages></flash-messages>с angular 5.

Вам просто нужно добавить следующие строки в файл app.module.ts

import { ---, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FlashMessageModule } from "angular-flash-message";


@NgModule({
  ---------------
  imports: [
    FlashMessageModule,
    ------------------         
  ], 
  -----------------
  schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
  ------------
})

NB: я использую его для сообщений flash-сообщений

reza.cse08
источник
Единственное решение моей проблемы, с которой я столкнулся с 2 часов
Вероника,
7

В вашем компоненте планировщика вы должны отсутствовать import HeaderAreaComponent, например:

import { HeaderAreaComponent } from '../header-area.component'; 
//change path according your project

Кроме того, убедитесь, что все компоненты и каналы должны быть объявлены через NgModule .

Посмотрим, поможет ли это.

Sanket
источник
К сожалению, нет - ошибка остается прежней, и импорт помечается lint как неиспользуемый.
frot.io
не могли бы вы опубликовать полный код вашего NgModule и компонента планировщика?
Санкет
1
В дополнение к предложению Гюнтера, приведенному выше, также попробуйте импортировать BrowserModule в свой компонент планировщика, например:import { BrowserModule } from '@angular/platform-browser';
Санкет
Я импортировал его в компонент планировщика и в модуль с объявлением импорта - все равно безуспешно.
frot.io 05
1
теперь попробуйте добавить CalculationService в провайдеры NgModule, как этоproviders: [CalculationService],
Sanket
6

Я столкнулся с этой проблемой на Angular 7, и проблема заключалась в том, что после создания модуля я не выполнял ng build. Итак, я выступил -

  • ng build
  • ng serve

и это сработало.

Шайлеш Пратапвар
источник
просто запустить ng serve снова сделало это для меня, хотя и довольно
Elger Mensonides
4

Ошибка в модульном тесте, когда компонент отсутствует <router-outlet>на главной странице приложения. поэтому следует определить компонент в тестовом файле, как показано ниже.

<app-header></app-header>
<router-outlet></router-outlet>

а затем необходимо добавить в файл spec.ts, как показано ниже.

import { HeaderComponent } from './header/header.component';

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [
        App`enter code here`Component,
        HeaderComponent <------------------------
      ],
    }).compileComponents();
  }));
});
Farzad.Kamali
источник
3

Другой возможной причиной того же сообщения об ошибке является несоответствие между именем тега и именем селектора. В этом случае:

<header-area></header-area>имя тега должно точно совпадать 'header-area'с объявлением компонента:

@Component({
  selector: 'header-area',
Алексей
источник
2

У меня была такая же проблема с angular RC.6, по какой-то причине он не позволяет передавать компонент другому компоненту, используя директивы в качестве декоратора компонента для родительского компонента.

Но если вы импортируете дочерний компонент через модуль приложения и добавите его в массив объявлений, ошибка исчезнет. Нет особого объяснения, почему это проблема с angular rc.6

Эммануэль Марики
источник
2

Когда у меня возникла эта проблема, это произошло потому, что я использовал 'templateUrl' вместо просто 'template' в декораторе, поскольку я использую webpack и мне нужно использовать в нем require . Просто будьте осторожны с именем декоратора, в моем случае я сгенерировал шаблонный код с помощью сниппета, декоратор был создан как:

@Component({
  selector: '',
  templateUrl: 'PATH_TO_TEMPLATE'
})

но для веб-пакета декоратором должен быть просто ' template ' НЕ ' templateUrl ', например:

@Component({
  selector: '',
  template: require('PATH_TO_TEMPLATE')
})

изменение этого решило проблему для меня.

хотите узнать больше о двух методах? прочтите этот средний пост о templatevstemplateUrl

Лео Боттаро
источник
2

Я получил эту ошибку, когда у меня было несоответствие экспортированного имени файла и класса:

имя файла: list.component.ts

экспортированный класс: ListStudentsComponent

Переход с ListStudentsComponent на ListComponent устранил мою проблему.

GonnaGetGet
источник
2

Я столкнулся с этой проблемой. Ошибка: ошибки синтаксического анализа шаблона: 'app-login' не известен ... с ng test. Я попробовал все вышеперечисленные ответы: ничего не помогло.

РЕШЕНИЕ ДЛЯ ТЕСТА NG:

Angular 2 Karma Test 'имя-компонента' не является известным элементом

<= Я добавил объявления для обижая компонентов в beforEach(.. declarations[])к app.component.spec.ts .

ПРИМЕР app.component.spec.ts

...
import { LoginComponent } from './login/login.component';
...
describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        ...
      ],
      declarations: [
        AppComponent,
        LoginComponent
      ],
    }).compileComponents();
  ...
paulsm4
источник
2

У меня была такая же проблема, и я исправил, добавив компонент (MyComponentToUse) в массив экспорта в модуле, в котором был объявлен мой компонент (ModuleLower). Затем я импортирую ModuleLower в ModuleHigher, поэтому теперь я могу повторно использовать свой компонент (MyComponentToUse) в ModuleLower и ModuleHigher.

            @NgModule({
              declarations: [
                MyComponentToUse
              ],
              exports: [
                MyComponentToUse
              ]
            })
            export class ModuleLower {}


            @NgModule({
              imports: [
                ModuleLower
              ]
            })
            export class ModuleHigher {} 
Ильес ШЕРИФ
источник
Собственно, просто нужно экспортировать компонент.
Rohit Parte
1

У меня была такая же проблема с Angular 7, когда я собирался улучшить тестовый модуль, объявив тестовый компонент. Просто добавил schemas: [ CUSTOM_ELEMENTS_SCHEMA ]следующее, и ошибка была решена.

TestBed.configureTestingModule({
  imports: [ReactiveFormsModule, FormsModule],
  declarations: [AddNewRestaurantComponent],
  schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
});
Чамила Мэддумадж
источник
1

Для будущих проблем. Если вы думаете, что следовали всем правильным ответам, и все же проблема существует.

Попробуйте выключить и снова включить сервер.

У меня была такая же проблема, я выполнил все шаги, но не смог ее решить. Выключили, включили и это было исправлено.

Лена Тевар
источник
Сначала думал, что надо только перезагрузить npm start(под водой ng serve). Иногда это помогает прояснить проблемы. Теперь мне пришлось полностью перезапустить Visual Studio Code.
Майк де Клерк,
0

В моем случае ошибка новичка генерировала то же сообщение об ошибке.

app-rootТег не присутствовал в index.html

Фелипе Андраде
источник
0

OnInitбыл автоматически реализован в моем классе при использовании ng new ...ключевой фразы в angular CLI для создания нового компонента. Итак, после того как я удалил реализацию и удалил пустой метод, который был сгенерирован, проблема решена.

Огюст
источник
0

Для меня путь для templateUrl был неправильным

Я использовал

торгово-список-edit.component.html

Тогда как это должно было быть

./shopping-list-edit.component.html

Глупая ошибка, но случающаяся при запуске. Надеюсь, что это поможет кому-то в беде.

Мина Чаудхари
источник
0

Поздний ответ на тему, но я уверен, что есть больше людей, которые могут использовать эту информацию, объясненную с другой точки зрения.

В Ionic пользовательские компоненты angular организованы в отдельный модуль под названием ComponentsModule. Когда первый компонент генерируется с использованием ionic generate component, наряду с компонентом, ionic генерирует ComponentsModule. Любые последующие компоненты добавляются в один и тот же модуль, и это правильно.

Вот образец ComponentsModule

import { NgModule } from '@angular/core';
import { CustomAngularComponent } from './custom/custom-angular-component';
import { IonicModule } from 'ionic-angular';
@NgModule({
    declarations: [CustomAngularComponent],
    imports: [IonicModule],
    exports: [CustomAngularComponent],
    entryComponents:[

      ]
})
export class ComponentsModule {}

Чтобы использовать ComponentsModuleв приложении, как и любые другие модули angular, их ComponentsModulesнеобходимо импортировать в AppModule. Компонент ionic generate (v 4.12) не добавляет этот шаг, поэтому его нужно добавлять вручную.

Выдержка из AppModule:

@NgModule({
  declarations: [
    //declaration
  ],
  imports: [
    //other modules 
    ComponentsModule,
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    //ionic pages
  ],
  providers: [
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler},
    //other providers
  ]
})
export class AppModule {}
Арагорн
источник
-1

Хорошо, позвольте мне подробно описать код, как использовать другой компонент модуля.

Например, у меня есть модуль M2, модуль M2 имеет компонент comp23 и компонент comp2. Теперь я хочу использовать comp23 и comp2 в app.module, вот как:

это app.module.ts, см. мой комментарий,

 // import this module's ALL component, but not other module's component, only this module
  import { AppComponent } from './app.component';
  import { Comp1Component } from './comp1/comp1.component';

  // import all other module,
 import { SwModule } from './sw/sw.module';
 import { Sw1Module } from './sw1/sw1.module';
 import { M2Module } from './m2/m2.module';

   import { CustomerDashboardModule } from './customer-dashboard/customer-dashboard.module';


 @NgModule({

    // declare only this module's all component, not other module component.  

declarations: [
AppComponent,
Comp1Component,


 ],

 // imports all other module only.
imports: [
BrowserModule,
SwModule,
Sw1Module,
M2Module,
CustomerDashboardModule // add the feature module here
],
 providers: [],
 bootstrap: [AppComponent]
})
export class AppModule { }

это модуль m2:

   import { NgModule } from '@angular/core';
   import { CommonModule } from '@angular/common';

   // must import this module's all component file
   import { Comp2Component } from './comp2/comp2.component';
   import { Comp23Component } from './comp23/comp23.component';

   @NgModule({

   // import all other module here.
     imports: [
       CommonModule
     ],

    // declare only this module's child component. 
     declarations: [Comp2Component, Comp23Component],

   // for other module to use these component, must exports
     exports: [Comp2Component, Comp23Component]
   })
   export class M2Module { }

Моя рекомендация в коде объясняет, что вам здесь нужно делать.

теперь в app.component.html вы можете использовать

  <app-comp23></app-comp23>

следовать модулю импорта образца документа angular

hoogw
источник