CUSTOM_ELEMENTS_SCHEMA ajouté à NgModule.schemas affichant toujours une erreur

137

Je viens de passer de Angular 2 rc4 à rc6 et j'ai des problèmes pour 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 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 { }

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 surmonter l'erreur. Mais cela ne semble pas fonctionner. Qu'est-ce que je fais mal? (J'espère que ce n'est rien d'évident que je ne vois pas pour le moment. J'ai passé les 6 dernières heures à passer à cette version ...)

Raphael Hippe
la source
1
Si vous l'ajoutez à votre AppModule, devez-vous toujours l'ajouter à votre composant?
Alessandro Resta
1
même ici, pour moi, ajouter simplement "schémas: [CUSTOM_ELEMENTS_SCHEMA]" a fonctionné comme un charme. Merci :)
AIon
3
Il serait utile que vous ajoutiez votre "Correctif" en tant que réponse à cette question, afin que les autres personnes qui rencontrent votre question comprennent exactement comment ils peuvent bénéficier de l'utilisation de votre solution:]
Danny Bullis

Réponses:

97

Je voulais juste ajouter un peu plus à ce sujet.

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

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

EDIT: La schemasdéclaration doit être chez un @NgModuledécorateur. L'exemple ci-dessous montre un module personnalisé avec un composant personnalisé CustomComponentqui autorise n'importe quelle balise 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>
Caleb
la source
J'ai une application très simple qui a plusieurs composants dans un seul module. Je l'ai ajouté à mon module ... J'ai toujours des erreurs ...
Nicolas Irisarri
7
Merci Caleb. J'obtenais les erreurs lors de l'exécution d'un test simple. Je l'ai compris cependant ... Je n'ajoutais pas le CUSTOM_ELEMENTS_SCHEMAfaux module de test unitaire. Dès que j'ai fait ça, il a cessé de se plaindre.
Nicolas Irisarri
1
Existe-t-il un moyen de définir des éléments personnalisés qui sont autorisés? L'utilisation CUSTOM_ELEMENTS_SCHEMApourrait conduire à des erreurs difficiles à trouver, mais j'aimerais utiliser des noms d'élément personnalisés pour les ng-contentsections de mes contrôles sans que ces noms d'élément spécifiques provoquent des erreurs et sans créer de composants pour eux qui ne seraient que ng-content ...
Jason Goemaat
1
@Caleb pouvez-vous s'il vous plaît fournir un exemple de code rapide de ce que vous entendez par Il semble que la ligne schemas: [ CUSTOM_ELEMENTS_SCHEMA ]doit être ajoutée à chaque composant où vous utilisez des balises HTML ? Il semble que le Componentdécorateur n'accepte pas de schemasparamètre.
Danny Bullis
2
Salut @DannyBullis, au lieu du Componentdécorateur, on le trouve dans le NgModuledécorateur. Vous devrez créer un module pour ce composant, puis vous pourrez y spécifier le schéma. Lien vers des documents et un exemple.
Caleb
85

Ceci est résolu par:

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.

Raphael Hippe
la source
7
n'oubliez pas de le déclarer ... il se trouve dans @ angular / core. Quelque chose comme ça devrait convenir:import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
rlasjunies
Ce post pourrait vous aider avec la procédure à suivre: medium.com/google-developer-experts/…
Carlos E
1
l'ajout de schémas: [CUSTOM_ELEMENTS_SCHEMA] à CHAQUE composant, a fait l'affaire! Merci!
Pedro Ferreira
les schémas n'existent pas dans angulaire 9
Renil Babu
37

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 la façon dont la configuration de header.component.spec.ts commencerait:

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();
  }));
Dan Stirling-Talbert
la source
1
Merci! Cela m'a pris beaucoup trop de temps # & @% pour le trouver.
eflat
23

Ajoutez ce qui suit sous @NgModule({})dans '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 { }
Negin
la source
2
mais maintenant, toute votre application autorise les balises personnalisées.
EE33 du
10

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

CUSTOM_ELEMENTS_SCHEMA

pour

NO_ERRORS_SCHEMA

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

Maintenant ça marche.

Martin Cremer
la source
Agréable! Cela a fonctionné pour moi. Je voulais ajouter des éléments XML sur mon composant HTML et j'obtenais des erreurs. Merci beaucoup
Celso Soares
servait des éléments angulaires dans des éléments angulaires dans des éléments angulaires (Angular 8) l'ajout CUSTOM_ELEMENTS_SCHEMAn'a pas aidé mais NO_ERRORS_SCHEMAa fait l'affaire et toute l'imbrication d'éléments angulaires autonomes fonctionne maintenant comme un charme
Yogi
Cela a fonctionné pour moi TestBed. L'élément fonctionnait bien mais le test échouait. Ajouté schemas: [NO_ERRORS_SCHEMA], et tout va bien.
VSO
9

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{};

LogoutComponent doit être exporté

dashboard.module.ts
import AccountModuledans le module où nous voulons utiliser<app-logout> import {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 cela ne fonctionne pas lorsque dashboard.module est chargé paresseusement.
Lors de l'utilisation CUSTOM_ELEMENTS_SCHEMAen cas de chargement différé, l'erreur est supprimée mais le composant n'est pas ajouté à dom.

Arun
la source
idem +1 plus d'erreur, mais plus de mise à jour dom, cette solution de contournement pour essayer de faire fonctionner ces sélecteurs avec '-' est #### !!! && ù * $
user1568220
1
Merci beaucoup, après une semaine, j'ai découvert que cela ne pouvait pas fonctionner avec le chargement paresseux en ionique
Amr.Ayoub
1
@Arun - votre solution est précise à 100%, 1) besoin d'ajouter à l'exportation et 2) pas besoin de custom_elements_schema
Ashwin
J'ai eu la même erreur et j'ai mis mes composants dans chaque module où j'avais besoin dans les déclarations clausule. Je n'ai pas utilisé CUSTOM_ELEMENTS_SCHEMA et j'ai travaillé.
David
6

Avec les composants contenant du matériau angulaire, une erreur similaire s'est produite avec mes tests unitaires. Selon la réponse de @Dan Stirling-Talbert ci-dessus, ajouté ceci à 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.

T. Bulford
la source
4

Il suffit de lire cet article et selon la documentation angulaire 2:

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 rencontre ce problème, une fois que vous avez ajouté CUSTOM_ELEMENTS_SCHEMA à votre NgModule, assurez-vous que tout nouvel élément personnalisé que vous utilisez a un «tiret» dans son nom, par exemple. ou etc.

Hugo 1005
la source
1
Un tiret dans le nom? Pourquoi imposer une convention aussi stupide?
Meryan
Je ne rencontre cela que lorsque je viens de commencer à utiliser le chargement paresseux dans Ionic3 et uniquement lorsque j'essaye de créer pour le Web. Veuillez publier le lien vers les documents que vous mentionnez. Je vous remercie.
Meryan
3

C'est un article assez long et il donne une explication plus détaillée du problème.

Le problème (dans mon cas) survient lorsque vous avez une projection de contenu multi-slot

Voir aussi projection de contenu 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>

fichier ts:

@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 puis vous obtenez des erreurs d'analyse de modèle qui ne sont pas un composant angulaire connu et en fait ce n'est pas le cas - il s'agit simplement d'une référence à un contenu ng dans votre composant:

Et puis la solution la plus simple consiste à ajouter

schemas: [
    CUSTOM_ELEMENTS_SCHEMA
],

... à votre app.module.ts


Mais il existe une approche simple et propre à ce problème - au lieu d'utiliser <my-component-header>pour insérer du code HTML dans l'emplacement là-bas - 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 donc il n'y a pas de problèmes là-dedans, pas d'erreurs, pas 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 - utiliser votre composant de cette façon ne génère pas d'erreurs et est plus clair.

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

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

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

Combiner
la source
1
c'était exactement ce que je cherchais, merci pour le partage!
romeouald
1

Je voudrais ajouter une 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 avoir la déclaration du composant enfant, AINSI QUE LE COMPOSANT ENFANT DE L'ENFANT. Cela a finalement résolu le problème pour moi.

ganders
la source
1

Je pense que vous utilisez un module personnalisé. Vous pouvez essayer ce qui suit. Vous devez ajouter ce qui suit au fichier your-module.module.ts :

import { GridModule } from '@progress/kendo-angular-grid';
@NgModule({
  declarations: [ ],
  imports: [ CommonModule, GridModule ],
  exports: [ ],
})
Vương Hữu Thiện
la source
0

Cela n'a pas fonctionné pour moi (en utilisant 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 le fichier de spécifications.

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

  beforeEach(() => {

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

    });
HMagdy
la source
0

Pour moi, j'avais besoin de 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 declarationssection.

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 { }
Denise Mauldin
la source
0

Je viens d'importer ClarityModuleet cela a résolu tous les problèmes. Essaie!

import { ClarityModule } from 'clarity-angular';

Incluez également le module dans les importations.

imports: [ ClarityModule ],

Ishani
la source
Hé, Ishani. Pouvez-vous s'il vous plaît également ajouter une explication pour pourquoi cela fonctionne?
f.khantsis
Si nous visitons la documentation de CUSTOM_ELEMENTS_SCHEMA, sur angular.io/api/core/CUSTOM_ELEMENTS_SCHEMA, nous verrons que CUSTOM_ELEMENTS_SCHEMA permet à NgModule de contenir des éléments non angulaires avec un tiret (-) {similaire à ce scénario}. Le module de clarté une fois importé inclut toutes les icônes clr, etc. par défaut et nous pouvons également utiliser d'autres fonctionnalités du module de clarté.
Ishani
Cela n'a aucun rapport avec le problème ici. Comment le résoudre en important le module de clarté? @Ishani
HelloWorld
si vous lisez l'énoncé du problème, Angular n'est pas en mesure d'identifier clr-header. La même erreur vient pour clr-iconet d'autres. Comme je l'ai mentionné dans mon commentaire précédent, le module Clarity les contient par défaut. J'espère que cela a répondu à votre question.
Ishani le
0

a résolu ce problème dans le fichier /app/app.module.ts

importez votre composant et déclarez-le

import { MyComponent } from './home-about-me/my.component';

@NgModule({
  declarations: [
    MyComponent,
  ]
Luis Lobo
la source
-3

Avez-vous utilisé le webpack ... si oui, veuillez installer

angular2-template-loader

et le mettre

test: /\.ts$/,
   loaders: ['awesome-typescript-loader', 'angular2-template-loader']
Imanullah
la source
Je ne peux pas tracer les tests par défaut qui avaient été créés par le composant généré par ng g et qui ont eu la même erreur. Rien de ce sujet n'a été utile: (Je supprime une erreur uniquement lorsque j'ai été commenté les fichiers de spécifications des composants :(
Nesquik27
Je comprends bien que les balises personnalisées fonctionnaient uniquement avec angular ci-dessous v2?! J'ai vérifié quelque chose sur youtube et j'essaie de tester mon code de v2 dans un environnement v4
Nesquik27