web-dev-qa-db-fra.com

CUSTOM_ELEMENTS_SCHEMA ajouté à NgModule.schemas affichant toujours une erreur

Je viens de passer de Angular 2 rc4 à rc6 et des difficultés à le faire.

Je vois l'erreur suivante sur ma console:

Unhandled Promise rejection: Template parse errors:
'cl-header' is not a known element:
1. If 'cl-header' is an Angular component, then verify that it is part of this module.
2. If 'cl-header' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schema' of this component to suppress this message. ("<main>
    [ERROR ->]<cl-header>Loading Header...</cl-header>
    <div class="container-fluid">
      <cl-feedbackcontai"): AppComponent@1:4

Voici mon composant d'en-tête:

import { Component } from '@angular/core';
import { Router } from '@angular/router';

// own service
import { AuthenticationService } from '../../../services/authentication/authentication.service.ts';

import '../../../../../public/css/styles.css';

@Component({
  selector: 'cl-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent { // more code here... }

Voici mon module d'en-tête:

import { NgModule, CUSTOM_ELEMENTS_SCHEMA }      from '@angular/core';
import { RouterModule } from '@angular/router';
import { CommonModule }      from '@angular/common';
import { FormsModule }      from '@angular/forms';

import { HeaderComponent }  from './../../../components/util_components/header/header.component.ts';

@NgModule({
    declarations: [ HeaderComponent ],
    bootstrap:    [ HeaderComponent ],
    imports: [ RouterModule, CommonModule, FormsModule ],
    schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
})
export class HeaderModule { }

J'ai créé un module de wrapper appelé module util qui importe le HeaderModule:

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

import {HeaderModule} from "./header/header.module";
// ...

@NgModule({
    declarations: [ ],
    bootstrap:    [ ],
    imports: [ HeaderModule]
})
export class UtilModule { }

Ce qui est finalement importé par l'AppModule:

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

import { BrowserModule } from '@angular/platform-browser';

import { AppComponent }  from './app.component';

import {UtilModule} from "./modules/util_modules/util.module";
import {RoutingModule} from "./modules/routing_modules/routing.module";

@NgModule({
    bootstrap: [AppComponent],
    declarations: [AppComponent],
    imports: [BrowserModule, UtilModule, RoutingModule]
})
export class AppModule { }

À ma connaissance, je suis les instructions du message d’erreur en utilisant le SCHEMA pour supprimer l’erreur. Mais cela ne semble pas fonctionner. Qu'est-ce que je fais mal? (J'espère que ce n'est pas évident, je ne le vois pas pour le moment. Cela fait 6 heures que je passe à la version actuelle ...)

114
Raphael Hippe

Hé c'est réparé en faisant

a) ajouter schemas: [ CUSTOM_ELEMENTS_SCHEMA ] à chaque composant ou

b) ajouter

import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

et

schemas: [
    CUSTOM_ELEMENTS_SCHEMA
],

à votre module.

À la vôtre, Raphaël

74
Raphael Hippe

Je voulais juste ajouter un peu plus à ce sujet.

Avec la nouvelle version angular 2.0.0 (14 septembre 2016), si vous utilisez des balises HTML personnalisées, la fonction Template parse errors sera signalée. Une balise personnalisée est une balise que vous utilisez dans votre code HTML et qui ne fait pas partie de ces balises .

Il semble que la ligne schemas: [ CUSTOM_ELEMENTS_SCHEMA ] doive être ajoutée à chaque composant pour lequel vous utilisez des balises HTML personnalisées.

EDIT: La déclaration schemas doit être dans un décorateur @NgModule. L'exemple ci-dessous montre un module personnalisé avec un composant personnalisé CustomComponent qui autorise toutes les balises HTML dans le modèle html pour ce composant.

custom.module.ts

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

import { CustomComponent } from './custom.component';

@NgModule({
  declarations: [ CustomComponent ],
  exports: [ CustomComponent ],
  imports: [ CommonModule ],
  schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
})
export class CustomModule {}

custom.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'my-custom-component',
  templateUrl: 'custom.component.html'
})
export class CustomComponent implements OnInit {
  constructor () {}
  ngOnInit () {}
}

custom.component.html

Ici, vous pouvez utiliser n’importe quelle balise HTML de votre choix.

<div class="container">
  <boogey-man></boogey-man>
  <my-minion class="one-eyed">
    <job class="plumber"></job>
  </my-minion>
</div>
85
Caleb

Cela peut également se produire lors de l'exécution de tests unitaires si vous testez un composant avec des éléments personnalisés. Dans ce cas, custom_elements_schema doit être ajouté au testingModule qui est configuré au début du fichier .spec.ts pour ce composant. Voici un exemple de démarrage de l'installation de header.component.spec.ts:

import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

describe('HeaderComponent', () => {
  let component: HeaderComponent;
  let fixture: ComponentFixture<HeaderComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [PrizeAddComponent],
      schemas: [
        CUSTOM_ELEMENTS_SCHEMA
      ],
    })
      .compileComponents();
  }));
24

Ajoutez les éléments suivants sous @NgModule({})in 'app.module.ts':

import CUSTOM_ELEMENTS_SCHEMA from `@angular/core`;

puis

schemas: [
    CUSTOM_ELEMENTS_SCHEMA
]

Votre 'app.module.ts' devrait ressembler à ceci:

import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

@NgModule({
  declarations: [],
  imports: [],
  schemas: [ CUSTOM_ELEMENTS_SCHEMA],
  providers: [],
  bootstrap: [AppComponent]
})

export class AppModule { }
13
Negin

Cela n'a pas fonctionné pour moi non plus. j'ai changé

CUSTOM_ELEMENTS_SCHEMA

for

NO_ERRORS_SCHEMA

qui a été suggéré dans cet article: https://scotch.io/tutorials/angular-2-transclusion-using-ng-content

Maintenant ça marche.

8
Martin Cremer

util.component.ts

@Component({
    selector: 'app-logout',
    template: `<button class="btn btn-primary"(click)="logout()">Logout</button>`
})
export class LogoutComponent{}

util.module.ts

@NgModule({
    imports: [...],
    exports: [
        LogoutComponent
    ],
    declarations: [LogoutComponent]
})
export class AccountModule{};

Le composant LogoutComponent doit être exporté

dashboard.module.ts
importer AccountModule dans le module où nous voulons utiliser <app-logout> importer {AccountModule} de 'util.module';

@NgModule({
  imports: [
    CommonModule, AccountModule
  ],
  declarations: [DashboardComponent]
})
export class DashboardModule { }

dashboard.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-dashboard',
  template: `<div><app-logout></app-logout></div>`
})
export class DashboardComponent implements OnInit {
  constructor() {}
  ngOnInit() {}
}

Je ne suis pas obligé d'importer et d'utiliser CUSTOM_ELEMENTS_SCHEMA.
Cependant, il ne fonctionne pas lorsque dashboard.module est chargé paresseux.
Lors de l'utilisation de CUSTOM_ELEMENTS_SCHEMA en cas de chargement différé, l'erreur est supprimée mais le composant n'est pas ajouté à dom.

7
Arun

Il suffit de lire ce post et selon le angular 2 docs:

export CUSTOM_ELEMENTS_SCHEMA
Defines a schema that will allow:

any non-Angular elements with a - in their name,
any properties on elements with a - in their name which is the common rule for custom elements.

Donc, juste au cas où quelqu'un rencontrerait ce problème, une fois que vous aurez ajouté CUSTOM_ELEMENTS_SCHEMA à votre NgModule, assurez-vous que tout nouvel élément personnalisé que vous utilisez possède un "tiret" dans son nom, par exemple. ou etc.

4
Hugo 1005

Cet article est plutôt long et donne une explication plus détaillée du problème.

Le problème (dans mon cas) vient quand vous avez Projection de contenu sur plusieurs emplacements

Voir aussi projection de conten pour plus d'informations.

Par exemple, si vous avez un composant qui ressemble à ceci:

fichier html:

 <div>
  <span>
    <ng-content select="my-component-header">
      <!-- optional header slot here -->
    </ng-content>
  </span>

  <div class="my-component-content">
    <ng-content>
      <!-- content slot here -->
    </ng-content>
  </div>
</div>

ts fichier:

@Component({
  selector: 'my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.scss'],
})
export class MyComponent {    
}

Et vous voulez l'utiliser comme:

<my-component>
  <my-component-header>
    <!-- this is optional --> 
    <p>html content here</p>
  </my-component-header>


  <p>blabla content</p>
  <!-- other html -->
</my-component>

Et ensuite, vous obtenez des erreurs d’analyse de modèle qui ne sont pas un composant connu Angular et le fait est qu’il ne l’est pas - c’est simplement une référence à un contenu ng dans votre composant:

Et puis le correctif le plus simple est d'ajouter

schemas: [
    CUSTOM_ELEMENTS_SCHEMA
],

... à votre app.module.ts


Mais il y a une approche simple et propre à ce problème - au lieu d'utiliser <my-component-header> pour insérer du HTML dans le logement, vous pouvez utiliser un nom de classe pour cette tâche comme ceci:

fichier html:

 <div>
  <span>
    <ng-content select=".my-component-header">  // <--- Look Here :)
      <!-- optional header slot here -->
    </ng-content>
  </span>

  <div class="my-component-content">
    <ng-content>
      <!-- content slot here -->
    </ng-content>
  </div>
</div>

Et vous voulez l'utiliser comme:

<my-component>
  <span class="my-component-header">  // <--- Look Here :) 
     <!-- this is optional --> 
    <p>html content here</p>
  </span>


  <p>blabla content</p>
  <!-- other html -->
</my-component>

Donc ... plus de composants qui n'existent pas, il n'y a donc aucun problème, aucune erreur, plus besoin de CUSTOM_ELEMENTS_SCHEMA dans app.module.ts

Donc, si vous étiez comme moi et que vous ne vouliez pas ajouter CUSTOM_ELEMENTS_SCHEMA au module, l'utilisation de votre composant de cette manière ne génère pas d'erreur, mais est plus claire.

Pour plus d'informations sur ce problème - https://github.com/angular/angular/issues/11251

Pour plus d'informations sur Angular projection de contenu - https://blog.angular-university.io/angular-ng-content/

Vous pouvez aussi voir https://scotch.io/tutorials/angular-2-transclusion-using-ng-content

3
Combine

J'aimerais ajouter un élément d'information supplémentaire, car la réponse acceptée ci-dessus n'a pas complètement corrigé mes erreurs.

Dans mon scénario, j'ai un composant parent, qui contient un composant enfant. Et ce composant enfant contient également un autre composant.

Ainsi, le fichier de spécification de mon composant parent doit comporter la déclaration du composant enfant, ainsi que la composante enfant de l'enfant. Cela a finalement résolu le problème pour moi.

1
ganders

Pour moi, je devais regarder:

1. If 'cl-header' is an Angular component, then verify that it is part of this module.

Cela signifie que votre composant n'est pas inclus dans le app.module.ts. Assurez-vous qu'il est importé puis inclus dans la section declarations.

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

import { BrowserModule } from '@angular/platform-browser';

import { AppComponent }  from './app.component';

import { UtilModule } from "./modules/util_modules/util.module";
import { RoutingModule } from "./modules/routing_modules/routing.module";

import { HeaderComponent } from "./app/components/header.component";

@NgModule({
    bootstrap: [AppComponent],
    declarations: [
        AppComponent,
        HeaderComponent
    ],
    imports: [BrowserModule, UtilModule, RoutingModule]
})
export class AppModule { }
0
Denise Mauldin

Cela n'a pas fonctionné pour moi (avec 2.0.0). Ce qui a fonctionné pour moi a été d'importer RouterTestingModule à la place.

J'ai résolu ce problème en important RouterTestingModule dans un fichier de spécifications.

import {
    RouterTestingModule
} from '@angular/router/testing';

  beforeEach(() => {

        TestBed.configureTestingModule({
            providers: [
                App,
                AppState,
                Renderer,
                {provide: Router,  useClass: MockRouter }
            ],
            imports: [ RouterTestingModule ]
        });

    });
0
HMagdy

Avec les composants contenant Angular Material, une erreur similaire est survenue lors de mes tests unitaires. Selon la réponse de @Dan Stirling-Talbert ci-dessus, cela a été ajouté à mon fichier .spec de composant et l'erreur a été effacée de mes tests unitaires.

Import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'

Ajoutez ensuite le schéma dans l'instruction beforeEach () générée:

beforeEach(asyn(() => {
    declarations: [ AboutComponent ],
    schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
})
.compileComponents();
}));

Mon erreur Karma était la suivante: Si "mat-panel-title" est un composant Web, ajoutez "CUSTOM_ELEMENTS_SCHEMA" au "@ NgModule.schemas" de ce composant pour supprimer ce message.

0
T. Bulford