CUSTOM_ELEMENTS_SCHEMA wurde zu NgModule.schemas hinzugefügt und zeigt weiterhin Fehler an

137

Ich habe gerade ein Upgrade von Angular 2 rc4 auf rc6 durchgeführt und habe Probleme damit.

Auf meiner Konsole wird der folgende Fehler angezeigt:

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

Hier ist meine Header-Komponente:

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... }

Hier ist mein Header-Modul:

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

Ich habe ein Wrapper-Modul namens util-Modul erstellt, das das HeaderModule importiert:

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

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

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

Was schließlich vom AppModule importiert wird:

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

Nach meinem Verständnis folge ich den Anweisungen der Fehlermeldung und benutze das SCHEMA, um den Fehler zu unterdrücken. Aber es scheint nicht zu funktionieren. Was mache ich falsch? (Ich hoffe, es ist nichts Offensichtliches, was ich im Moment einfach nicht sehe. Ich habe die letzten 6 Stunden damit verbracht, auf diese Version zu aktualisieren ...)

Raphael Hippe
quelle
1
Wenn Sie AppModulees zu Ihrer Komponente hinzufügen, müssen Sie es dennoch zu Ihrer Komponente hinzufügen?
Alessandro Resta
1
Das gleiche hier, für mich hat das Hinzufügen von "Schemas: [CUSTOM_ELEMENTS_SCHEMA]" wie ein Zauber funktioniert. Vielen Dank :)
AIon
3
Es wäre hilfreich, wenn Sie Ihr "Fix" als Antwort auf diese Frage hinzufügen würden, damit anderen, die auf Ihre Frage stoßen, klar ist, wie sie von der Verwendung Ihrer Lösung profitieren können:]
Danny Bullis

Antworten:

97

Ich wollte nur ein bisschen mehr dazu hinzufügen.

Wenn Sie mit der neuen endgültigen Version von Angular 2.0.0 (14. September 2016) benutzerdefinierte HTML-Tags verwenden, wird dies gemeldet Template parse errors. Ein benutzerdefiniertes Tag ist ein Tag, das Sie in Ihrem HTML-Code verwenden und das nicht zu diesen Tags gehört .

Es sieht so aus, als schemas: [ CUSTOM_ELEMENTS_SCHEMA ]müsste die Zeile zu jeder Komponente hinzugefügt werden, in der Sie benutzerdefinierte HTML-Tags verwenden.

EDIT: Die schemasErklärung muss in einem @NgModuleDekorateur sein. Das folgende Beispiel zeigt ein benutzerdefiniertes Modul mit einer benutzerdefinierten Komponente CustomComponent, die ein beliebiges HTML-Tag in der HTML-Vorlage für diese eine Komponente zulässt.

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

Hier können Sie jedes gewünschte HTML-Tag verwenden.

<div class="container">
  <boogey-man></boogey-man>
  <my-minion class="one-eyed">
    <job class="plumber"></job>
  </my-minion>
</div>
Caleb
quelle
Ich habe eine sehr einfache App, die mehrere Komponenten in einem einzigen Modul enthält. Ich habe es meinem Modul hinzugefügt ... Ich bekomme immer noch Fehler ...
Nicolas Irisarri
7
Danke Caleb. Ich habe die Fehler beim Ausführen eines einfachen Tests erhalten. Ich habe es aber herausgefunden ... Ich habe das nicht CUSTOM_ELEMENTS_SCHEMAzu meinem Unit-Test-Fake-Modul hinzugefügt . Sobald ich das tat, hörte es auf, sich zu beschweren.
Nicolas Irisarri
1
Gibt es eine Möglichkeit, benutzerdefinierte Elemente zu definieren, die zulässig sind? Die Verwendung CUSTOM_ELEMENTS_SCHEMAkann zu Fehlern führen, die schwer zu finden sind. Ich möchte jedoch benutzerdefinierte Elementnamen für ng-contentAbschnitte in meinen Steuerelementen verwenden, ohne dass diese spezifischen Elementnamen Fehler verursachen, und ohne Komponenten für sie zu erstellen, die nur ng-Inhalt sind ...
Jason Goemaat
1
@Caleb Können Sie bitte ein kurzes Codebeispiel für Ihre Bedeutung bereitstellen ? Es sieht so aus, als schemas: [ CUSTOM_ELEMENTS_SCHEMA ]müsste die Zeile zu jeder Komponente hinzugefügt werden, in der Sie HTML-Tags verwenden . Es sieht so aus, als würde der ComponentDekorateur keinen schemasParameter akzeptieren .
Danny Bullis
2
Hey @DannyBullis, anstelle des ComponentDekorateurs befindet es sich im NgModuleDekorateur. Sie müssen ein Modul für diese Komponente erstellen und können dort das Schema angeben. Link zu Dokumenten und einem Beispiel.
Caleb
84

Dies wird behoben durch:

a) Hinzufügen schemas: [ CUSTOM_ELEMENTS_SCHEMA ]zu jeder Komponente oder

b) Hinzufügen

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

und

schemas: [
  CUSTOM_ELEMENTS_SCHEMA
],

zu Ihrem Modul.

Raphael Hippe
quelle
7
Vergessen Sie nicht, es zu deklarieren ... es befindet sich in @ angle / core. So etwas sollte passen:import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
Rlasjunies
Dieser Beitrag könnte bei der folgenden Vorgehensweise helfen: medium.com/google-developer-experts/…
Carlos E
1
Hinzufügen von Schemas: [CUSTOM_ELEMENTS_SCHEMA] zu JEDER Komponente, hat es geschafft! Vielen Dank!
Pedro Ferreira
Schemata existieren nicht in Winkel 9
Renil Babu
37

Dies kann auch beim Ausführen von Komponententests auftreten, wenn Sie eine Komponente mit benutzerdefinierten Elementen testen. In diesem Fall muss custom_elements_schema zum Testmodul hinzugefügt werden, das am Anfang der Datei .spec.ts für diese Komponente eingerichtet wird. Hier ist ein Beispiel dafür, wie das Setup von header.component.spec.ts beginnen würde:

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
quelle
1
Vielen Dank! Ich habe viel zu lange gebraucht, um das zu finden.
Eflat
23

Fügen Sie unter @NgModule({})'app.module.ts' Folgendes hinzu:

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

und dann

schemas: [
    CUSTOM_ELEMENTS_SCHEMA
]

Ihre 'app.module.ts' sollte folgendermaßen aussehen:

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

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

export class AppModule { }
Negin
quelle
2
Aber jetzt erlaubt Ihre gesamte App benutzerdefinierte Tags.
EE33
10

Es hat auch bei mir nicht funktioniert. ich habe mich verändert

CUSTOM_ELEMENTS_SCHEMA

zum

NO_ERRORS_SCHEMA

Dies wurde in diesem Artikel vorgeschlagen: https://scotch.io/tutorials/angular-2-transclusion-using-ng-content

Jetzt gehts.

Martin Cremer
quelle
Nett! Es hat bei mir funktioniert. Ich wollte XML-Elemente zu meiner HTML-Komponente hinzufügen und bekam Fehler. Vielen Dank
Celso Soares
Das Servieren von Winkelelementen innerhalb von Winkelelementen innerhalb von Winkelelementen (Winkel 8) CUSTOM_ELEMENTS_SCHEMAhat nicht geholfen, NO_ERRORS_SCHEMAaber den Trick getan, und das Verschachteln von eigenständigen Winkelelementen funktioniert jetzt wie ein Zauber
Yogi
Das hat bei mir weiter geklappt TestBed. Element funktionierte gut, aber der Test schlug fehl. Hinzugefügt schemas: [NO_ERRORS_SCHEMA], und es ist alles gut.
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 Muss exportiert werden

dashboard.module.ts
Import AccountModulein Modul, in dem<app-logout> import {AccountModule} aus 'util.module' verwendet werden soll;

@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() {}
}

Ich muss nicht importieren und verwenden CUSTOM_ELEMENTS_SCHEMA.
Es funktioniert jedoch nicht, wenn dashboard.module faul geladen ist.
Bei Verwendung CUSTOM_ELEMENTS_SCHEMAim Falle eines verzögerten Ladens wird ein Fehler unterdrückt, aber die Komponente wird nicht zu dom hinzugefügt.

Arun
quelle
idem +1 kein Fehler mehr, aber kein dom-Update mehr. Diese Problemumgehung für den Versuch, diese Selektoren mit '-' zum Laufen zu bringen, ist #### !!! && ù * $
user1568220
1
Vielen Dank, nach meiner Woche fand ich heraus, dass es nicht mit faulem Laden in ionic
funktionieren kann
1
@Arun - Ihre Lösung ist 100% genau, 1) muss zum Export hinzugefügt werden und 2) keine Notwendigkeit von custom_elements_schema
Ashwin
Ich hatte den gleichen Fehler und habe meine Komponenten in jedem Modul so eingestellt, wie ich es in Deklarationsklauseln brauchte. Ich habe CUSTOM_ELEMENTS_SCHEMA nicht verwendet und gearbeitet.
David
6

Bei Komponenten, die Angular Material enthalten, trat bei meinen Komponententests ein ähnlicher Fehler auf. Gemäß der obigen Antwort von @Dan Stirling-Talbert wurde dies zu meiner .spec-Komponentendatei hinzugefügt, und der Fehler wurde aus meinen Komponententests behoben.

Import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'

Fügen Sie dann das Schema in die generierte beforeEach () -Anweisung ein:

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

Mein Karma-Fehler war: Wenn 'mat-panel-title' eine Webkomponente ist, fügen Sie 'CUSTOM_ELEMENTS_SCHEMA' zu '@ NgModule.schemas' dieser Komponente hinzu, um diese Nachricht zu unterdrücken.

T. Bulford
quelle
4

Lesen Sie einfach diesen Beitrag und gemäß den eckigen 2 Dokumenten:

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.

Für den Fall, dass jemand auf dieses Problem stößt, stellen Sie nach dem Hinzufügen von CUSTOM_ELEMENTS_SCHEMA zu Ihrem NgModule sicher, dass jedes neue benutzerdefinierte Element, das Sie verwenden, einen Bindestrich im Namen hat, z. oder etc.

Hugo 1005
quelle
1
Ein Strich im Namen? Warum so eine dumme Konvention auferlegen?
Meryan
Ich bin nur darauf gestoßen, als ich gerade angefangen habe, Lazy Loading in Ionic3 zu verwenden, und nur, wenn ich versuche, für das Web zu bauen. Könnte bitte den Link zu den von Ihnen erwähnten Dokumenten posten. Danke dir.
Meryan
3

Dies ist ein ziemlich langer Beitrag, der eine detailliertere Erklärung des Problems enthält.

Das Problem (in meinem Fall) tritt auf, wenn Sie eine Multi Slot Content Projection haben

Siehe auch Inhaltsprojektion für weitere Informationen.

Zum Beispiel, wenn Sie eine Komponente haben, die so aussieht:

HTML-Datei:

 <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 Datei:

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

Und Sie möchten es wie folgt verwenden:

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


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

Und dann erhalten Sie Fehler beim Analysieren von Vorlagen, bei denen es sich nicht um eine bekannte Angular-Komponente handelt, und tatsächlich nicht - es handelt sich lediglich um einen Verweis auf einen ng-Inhalt in Ihrer Komponente:

Und dann ist die einfachste Lösung das Hinzufügen

schemas: [
    CUSTOM_ELEMENTS_SCHEMA
],

... zu Ihrer app.module.ts


Es gibt jedoch einen einfachen und übersichtlichen Ansatz für dieses Problem. Anstatt <my-component-header>HTML in den dortigen Steckplatz einzufügen, können Sie für diese Aufgabe einen Klassennamen wie den folgenden verwenden:

HTML-Datei:

 <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>

Und Sie möchten es wie folgt verwenden:

<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>

Also ... keine Komponenten mehr, die nicht existieren, also gibt es keine Probleme, keine Fehler, keine Notwendigkeit für CUSTOM_ELEMENTS_SCHEMA in app.module.ts

Wenn Sie also wie ich waren und CUSTOM_ELEMENTS_SCHEMA nicht zum Modul hinzufügen wollten, führt die Verwendung Ihrer Komponente auf diese Weise nicht zu Fehlern und ist klarer.

Weitere Informationen zu diesem Problem finden Sie unter https://github.com/angular/angular/issues/11251

Weitere Informationen zur Projektion von Angular-Inhalten finden Sie unter https://blog.angular-university.io/angular-ng-content/.

Sie können auch https://scotch.io/tutorials/angular-2-transclusion-using-ng-content sehen

Kombinieren
quelle
1
Das war genau das, wonach ich gesucht habe, danke fürs Teilen!
Romeouald
1

Ich möchte eine zusätzliche Information hinzufügen, da die oben akzeptierte Antwort meine Fehler nicht vollständig behoben hat.

In meinem Szenario habe ich eine übergeordnete Komponente, die eine untergeordnete Komponente enthält. Und diese untergeordnete Komponente enthält auch eine andere Komponente.

Die Spezifikationsdatei meiner übergeordneten Komponente muss also die Deklaration der untergeordneten Komponente sowie die KINDERKOMPONENTE DES KINDES enthalten. Das hat das Problem für mich endlich behoben.

Gander
quelle
1

Ich denke, Sie verwenden ein benutzerdefiniertes Modul. Sie können Folgendes versuchen. Sie müssen der Datei your-module.module.ts Folgendes hinzufügen :

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

Das hat bei mir nicht funktioniert (mit 2.0.0). Was für mich funktioniert hat, war stattdessen RouterTestingModule zu importieren.

Ich habe dieses Problem behoben, indem ich RouterTestingModule in die Spezifikationsdatei importiert habe.

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

  beforeEach(() => {

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

    });
HMagdy
quelle
0

Für mich musste ich schauen:

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

Dies bedeutet, dass Ihre Komponente nicht in der enthalten ist app.module.ts. Stellen Sie sicher, dass es importiert und dann in den declarationsAbschnitt aufgenommen wird.

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
quelle
0

Ich habe gerade importiert ClarityModuleund es hat alle Probleme gelöst. Versuche es!

import { ClarityModule } from 'clarity-angular';

Nehmen Sie das Modul auch in die Importe auf.

imports: [ ClarityModule ],

Ishani
quelle
Hey, Ishani. Können Sie bitte auch eine Erklärung hinzufügen, warum es funktioniert?
f.khantsis
Wenn wir die Dokumentation für CUSTOM_ELEMENTS_SCHEMAunter angle.io/api/core/CUSTOM_ELEMENTS_SCHEMA besuchen , werden wir feststellen, dass CUSTOM_ELEMENTS_SCHEMA es NgModule ermöglicht, Nicht-Angular-Elemente mit Bindestrich (-) {ähnlich wie in diesem Szenario} zu enthalten. Das importierte Klarheitsmodul enthält standardmäßig alle clr-Symbole usw., und wir können auch andere Funktionen des Klarheitsmoduls verwenden.
Ishani
Dies ist für das Problem hier irrelevant. Wie lösen Sie das Problem, indem Sie das Klarheitsmodul importieren? @Ishani
Hello World
Wenn Sie die Problemstellung lesen, kann Angular sie nicht identifizieren. clr-headerDer gleiche Fehler tritt auch bei clr-iconanderen auf. Wie ich in meinem vorherigen Kommentar erwähnt habe, enthält das Clarity-Modul diese standardmäßig. Ich hoffe es hat deine Frage beantwortet.
Ishani
0

Dieses Problem wurde in der Datei /app/app.module.ts behoben

Importieren Sie Ihre Komponente und deklarieren Sie sie

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

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

Haben Sie das Webpack verwendet ... wenn ja, bitte installieren

angular2-template-loader

und setzen Sie es

test: /\.ts$/,
   loaders: ['awesome-typescript-loader', 'angular2-template-loader']
Imanullah
quelle
Ich kann keine Standardtests verfolgen, die von der von ng g generierten Komponente erstellt wurden und denselben Fehler aufweisen. Nichts von diesem Thema war nicht hilfreich :( Ich
entferne
Ich verstehe richtig, dass benutzerdefinierte Tags nur mit Winkeln unter v2 arbeiteten?! Ich habe etwas in youtube überprüft und ich versuche, meinen Code von v2 in v4-Umgebung zu testen
Nesquik27