CUSTOM_ELEMENTS_SCHEMA dodany do NgModule.schemas nadal pokazuje błąd

137

Właśnie zaktualizowałem Angular 2 rc4 do rc6 i mam z tym problemy.

Widzę następujący błąd na mojej konsoli:

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

Oto mój składnik nagłówka:

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

Oto mój moduł nagłówkowy:

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

Utworzyłem moduł opakowujący o nazwie util module, który importuje HeaderModule:

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

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

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

Który jest ostatecznie importowany przez 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 { }

Zgodnie z moim zrozumieniem postępuję zgodnie z instrukcjami komunikatu o błędzie, używając SCHEMATU do usunięcia błędu. Ale wydaje się, że nie działa. Co ja robię źle? (Mam nadzieję, że to nic oczywistego, po prostu nie widzę w tej chwili. Spędziłem ostatnie 6 godzin na uaktualnianiu do tej wersji ...)

Raphael Hippe
źródło
1
Jeśli dodasz to do swojego AppModule, czy nadal musisz dodać go do swojego komponentu?
Alessandro Resta
1
to samo tutaj, dla mnie samo dodanie „schematów: [CUSTOM_ELEMENTS_SCHEMA]” działało jak urok. Dziękuję :)
AI dnia
3
Byłoby pomocne, gdybyś jako odpowiedź na to pytanie dodała swoją „Naprawę”, tak aby inni, którzy natknęli się na Twoje pytanie, wiedzieli, jakie korzyści mogą przynieść im Twoje rozwiązanie:]
Danny Bullis

Odpowiedzi:

97

Chciałem tylko dodać trochę więcej na ten temat.

W nowej ostatecznej wersji kątowej 2.0.0 (14 września 2016 r.), Jeśli użyjesz niestandardowych tagów HTML, zgłosi to Template parse errors. Tag niestandardowy to tag używany w kodzie HTML, który nie jest jednym z tych tagów .

Wygląda na to, że wiersz schemas: [ CUSTOM_ELEMENTS_SCHEMA ]należy dodać do każdego komponentu, w którym używasz niestandardowych tagów HTML.

EDIT:schemas deklaracja musi być w @NgModuledekoratora. Poniższy przykład pokazuje niestandardowy moduł z niestandardowym komponentem, CustomComponentktóry zezwala na dowolny tag html w szablonie HTML dla tego jednego komponentu.

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

Tutaj możesz użyć dowolnego tagu HTML, który chcesz.

<div class="container">
  <boogey-man></boogey-man>
  <my-minion class="one-eyed">
    <job class="plumber"></job>
  </my-minion>
</div>
Caleb
źródło
Mam bardzo prostą aplikację, która ma wiele komponentów w jednym module. Dodałem go do mojego modułu ... nadal
pojawiają
7
Dzięki Caleb. Otrzymywałem błędy podczas prostego testu. Rozgryzłem to jednak ... Nie dodałem CUSTOM_ELEMENTS_SCHEMAdo mojego fałszywego modułu testów jednostkowych. Jak tylko to zrobiłem, przestało narzekać.
Nicolas Irisarri
1
Czy istnieje sposób definiowania dozwolonych elementów niestandardowych? Używanie CUSTOM_ELEMENTS_SCHEMAmoże prowadzić do błędów, które są trudne do znalezienia, ale chciałbym używać niestandardowych nazw elementów dla ng-contentsekcji w moich kontrolkach bez tych konkretnych nazw elementów powodujących błędy i bez tworzenia dla nich komponentów, które byłyby po prostu ng-content ...
Jason Goemaat
1
@Caleb, czy możesz podać szybki przykład kodu tego, co masz na myśli. Wygląda na to, że wiersz schemas: [ CUSTOM_ELEMENTS_SCHEMA ]musi zostać dodany do każdego komponentu, w którym używasz tagów HTML ? Wygląda na to, że Componentdekorator nie akceptuje schemasparametru.
Danny Bullis
2
Hej @DannyBullis, zamiast Componentdekoratora, znajduje się w NgModuledekoratorze. Będziesz musiał utworzyć moduł dla tego komponentu, a następnie możesz określić tam schemat. Link do dokumentów i przykład.
Caleb
85

Jest to naprawiane przez:

a) dodanie schemas: [ CUSTOM_ELEMENTS_SCHEMA ]do każdego elementu lub

b) dodawanie

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

i

schemas: [
  CUSTOM_ELEMENTS_SCHEMA
],

do swojego modułu.

Raphael Hippe
źródło
7
nie zapomnij go zadeklarować ... znajduje się w @ angular / core. Coś takiego powinno pasować:import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
rlasjunies
Ten post może pomóc w procedurze, którą należy zastosować: medium.com/google-developer-experts/ ...
Carlos E
1
dodawanie schematów: [CUSTOM_ELEMENTS_SCHEMA] do KAŻDEGO komponentu, załatwiło sprawę! Dzięki!
Pedro Ferreira
schematy nie istnieją w kątowej 9
Renil Babu
37

Może się to również pojawić podczas uruchamiania testów jednostkowych, jeśli testujesz komponent z elementami niestandardowymi. W takim przypadku custom_elements_schema musi zostać dodany do testingModule, który jest konfigurowany na początku pliku .spec.ts dla tego komponentu. Oto przykład, jak powinna rozpocząć się instalacja 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();
  }));
Dan Stirling-Talbert
źródło
1
Dzięki! Znalezienie tego zajęło mi dużo czasu # & @%.
eflat
23

Dodaj następujące elementy @NgModule({})w „app.module.ts”:

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

i wtedy

schemas: [
    CUSTOM_ELEMENTS_SCHEMA
]

Twój „app.module.ts” powinien wyglądać następująco:

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

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

export class AppModule { }
Negin
źródło
2
ale teraz cała aplikacja zezwala na niestandardowe tagi.
EE33,
10

Na mnie też się nie udało. Zmieniłam

CUSTOM_ELEMENTS_SCHEMA

dla

NO_ERRORS_SCHEMA

co zostało zasugerowane w tym artykule: https://scotch.io/tutorials/angular-2-transclusion-using-ng-content

Teraz działa.

Martin Cremer
źródło
Miły! U mnie to zadziałało. Chciałem dodać elementy XML do kodu HTML mojego komponentu i otrzymywałem błędy. Wielkie dzięki
Celso Soares
obsługiwał elementy kątowe w elementach kątowych w elementach kątowych (Angular 8) dodawanie CUSTOM_ELEMENTS_SCHEMAnie pomogło, ale NO_ERRORS_SCHEMAzałatwiło sprawę i całe zagnieżdżanie samodzielnych elementów kątowych działa teraz jak urok
Yogi
To działało na mnie TestBed. Element działał poprawnie, ale test zakończył się niepowodzeniem. Dodano schemas: [NO_ERRORS_SCHEMA]i wszystko jest w porządku.
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 Musi zostać wyeksportowany

dashboard.module.ts
import AccountModulew module, w którym chcemy użyć<app-logout> importu {AccountModule} z '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() {}
}

Nie mam obowiązku importowania i używania CUSTOM_ELEMENTS_SCHEMA.
jednak nie działa, gdy moduł dashboard.module jest ładowany z opóźnieniem.
Podczas korzystania CUSTOM_ELEMENTS_SCHEMAz leniwego ładowania błąd jest pomijany, ale komponent nie jest dodawany do domeny.

Bieg
źródło
idem +1 nie ma więcej błędu, ale nie ma już aktualizacji domeny, to obejście umożliwiające działanie tych selektorów z '-' to #### !!! && ù * $
user1568220
1
Wielkie
1
@Arun - Twoje rozwiązanie jest w 100% dokładne, 1) trzeba je dodać do eksportu i 2) nie ma potrzeby stosowania custom_elements_schema
Ashwin
Miałem ten sam błąd i ustawiłem moje komponenty w każdym module, w którym potrzebowałem w klauzuli deklaracji. Nie używałem CUSTOM_ELEMENTS_SCHEMA i działałem.
David
6

W przypadku komponentów zawierających materiał kątowy podobny błąd wystąpił w moich testach jednostkowych. Zgodnie z powyższą odpowiedzią @Dan Stirling-Talbert, dodałem to do mojego pliku .spec komponentu, a błąd został usunięty z moich testów jednostkowych.

Import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'

Następnie dodaj schemat w wygenerowanej instrukcji beforeEach ():

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

Mój błąd Karmy brzmiał: Jeśli „mat-panel-title” jest składnikiem sieciowym, dodaj „CUSTOM_ELEMENTS_SCHEMA” do „@ NgModule.schemas” tego komponentu, aby ukryć ten komunikat.

T. Bulford
źródło
4

Po prostu przeczytaj ten post i zgodnie z kątowymi 2 dokumentami:

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.

Tak więc na wypadek, gdyby ktoś napotkał ten problem, po dodaniu CUSTOM_ELEMENTS_SCHEMA do NgModule upewnij się, że każdy nowy niestandardowy element, którego używasz, ma w nazwie `` myślnik '', np. lub itp.

Hugo 1005
źródło
1
Myślnik w nazwie? Po co narzucać tak głupią konwencję?
Meryan,
Wpadam na to tylko wtedy, gdy zacząłem używać leniwego ładowania w Ionic3 i tylko wtedy, gdy próbuję tworzyć dla sieci. Możesz zamieścić link do wymienionych dokumentów. Dziękuję Ci.
Meryan,
3

Jest to dość długi post i zawiera bardziej szczegółowe wyjaśnienie problemu.

Problem (w moim przypadku) pojawia się, gdy masz projekcję treści na wiele slotów

Zobacz także projekcję treści, aby uzyskać więcej informacji.

Na przykład, jeśli masz komponent, który wygląda tak:

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

plik ts:

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

I chcesz go używać tak, jak:

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


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

Następnie otrzymujesz błędy parsowania szablonu, które nie są znanym komponentem Angulara i tak naprawdę nie jest - to tylko odniesienie do zawartości ng w twoim komponencie:

A potem najprostszą poprawką jest dodanie

schemas: [
    CUSTOM_ELEMENTS_SCHEMA
],

... do twojego app.module.ts


Ale jest proste i przejrzyste podejście do tego problemu - zamiast <my-component-header>wstawiać html w tym slocie - możesz użyć nazwy klasy do tego zadania w następujący sposób:

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

I chcesz go używać tak, jak:

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

Więc ... koniec z nieistniejącymi komponentami, więc nie ma w tym żadnych problemów, żadnych błędów, nie ma potrzeby CUSTOM_ELEMENTS_SCHEMA w app.module.ts

Czyli gdybyś był taki jak ja i nie chciałeś dodawać CUSTOM_ELEMENTS_SCHEMA do modułu - użycie twojego komponentu w ten sposób nie generuje błędów i jest bardziej przejrzyste.

Więcej informacji na temat tego problemu - https://github.com/angular/angular/issues/11251

Więcej informacji na temat projekcji treści w Angular - https://blog.angular-university.io/angular-ng-content/

Możesz również zobaczyć https://scotch.io/tutorials/angular-2-transclusion-using-ng-content

Połączyć
źródło
1
właśnie tego szukałem, dzięki za udostępnienie!
romeouald
1

Chciałbym dodać jedną dodatkową informację, ponieważ powyższa zaakceptowana odpowiedź nie naprawiła całkowicie moich błędów.

W moim scenariuszu mam komponent nadrzędny, który przechowuje komponent podrzędny. Ten składnik potomny zawiera również inny składnik.

Tak więc plik specyfikacji mojego komponentu nadrzędnego musi mieć deklarację komponentu podrzędnego, RÓWNIEŻ JAKIEGO KOMPONENTU DZIECIĘCEGO. To ostatecznie rozwiązało problem.

ganders
źródło
1

Myślę, że używasz niestandardowego modułu. Możesz spróbować następujących rzeczy. Musisz dodać następujące elementy do pliku your-module.module.ts :

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

To nie zadziałało dla mnie (używając 2.0.0). Udało mi się zamiast tego zaimportować RouterTestingModule.

Rozwiązałem to, importując RouterTestingModule w pliku spec.

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

  beforeEach(() => {

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

    });
HMagdy
źródło
0

Dla mnie musiałem spojrzeć na:

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

Oznacza to, że Twój składnik nie jest uwzględniony w app.module.ts. Upewnij się, że został zaimportowany, a następnie uwzględniony w declarationssekcji.

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
źródło
0

Właśnie zaimportowałem ClarityModulei rozwiązałem wszystkie problemy. Spróbuj!

import { ClarityModule } from 'clarity-angular';

Dołącz także moduł do importu.

imports: [ ClarityModule ],

Ishani
źródło
Hej, Ishani. Czy możesz również dodać wyjaśnienie, dlaczego to działa?
f.khantsis
Jeśli przejrzymy dokumentację dla CUSTOM_ELEMENTS_SCHEMA, na angular.io/api/core/CUSTOM_ELEMENTS_SCHEMA, zobaczymy, że CUSTOM_ELEMENTS_SCHEMA pozwala NgModule na zawarcie elementów innych niż kątowe z myślnikiem (-) {podobnie do tego scenariusza}. Moduł jasności po zaimportowaniu zawiera domyślnie wszystkie ikony clr, itp. Możemy również korzystać z innych funkcji modułu przejrzystości.
Ishani
Nie ma to znaczenia dla problemu. Jak rozwiązać ten problem, importując moduł jasności? @Ishani
HelloWorld
jeśli czytasz opis problemu, Angular nie jest w stanie zidentyfikować clr-header. Ten sam błąd pojawia się w przypadku clr-iconinnych. Jak wspomniałem w moim poprzednim komentarzu, moduł Clarity zawiera je domyślnie. Mam nadzieję, że odpowiedział na twoje pytanie.
Ishani
0

rozwiązał ten problem w pliku /app/app.module.ts

zaimportuj swój komponent i zadeklaruj go

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

@NgModule({
  declarations: [
    MyComponent,
  ]
Luis Lobo
źródło
-3

Czy korzystałeś z pakietu internetowego ... Jeśli tak, zainstaluj

angular2-template-loader

i włóż to

test: /\.ts$/,
   loaders: ['awesome-typescript-loader', 'angular2-template-loader']
Imanullah
źródło
Nie mogę przypisać ścieżki testów domyślnych, które zostały utworzone przez komponent generujący przez ng g i otrzymały ten sam błąd. Nic z tego tematu nie było pomocne :(
Usuwam
Rozumiem, prawda, że ​​niestandardowe tagi działały tylko z kątowym poniżej v2 ?! Sprawdziłem coś na youtube i próbuję przetestować mój kod z v2 w środowisku v4
Nesquik27