CUSTOM_ELEMENTS_SCHEMA adicionado ao NgModule.schemas ainda mostrando o erro

137

Acabei de atualizar do Angular 2 rc4 para rc6 e com problemas para fazê-lo.

Eu vejo o seguinte erro no meu 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

Aqui está o meu componente de cabeçalho:

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

Aqui está o meu Módulo de cabeçalho:

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

Eu criei um módulo wrapper chamado módulo util que importa o HeaderModule:

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

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

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

Finalmente importado pelo 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 { }

Para meu entendimento, estou seguindo as instruções da mensagem de erro usando o ESQUEMA para suprimir o erro. Mas parece não funcionar. O que estou fazendo de errado? (Espero que não seja nada óbvio, apenas não vejo no momento. Passei as últimas 6 horas atualizando para esta versão ...)

Raphael Hippe
fonte
1
Se você o adicionar ao seu AppModule, ainda precisará adicioná-lo ao seu componente?
Alessandro Resta
1
o mesmo aqui, para mim, apenas adicionando "esquemas: [CUSTOM_ELEMENTS_SCHEMA]" funcionou como um encanto. Obrigado :)
Aion
3
Seria útil se você incluísse "Correção" como resposta a esta pergunta, para que fique claro para outras pessoas que se deparam com sua pergunta sobre exatamente como elas podem se beneficiar com o uso da sua solução:]
Danny Bullis

Respostas:

97

Só queria adicionar um pouco mais sobre isso.

Com a nova versão final angular 2.0.0 (14 de setembro de 2016), se você usar tags html personalizadas, ele informará isso Template parse errors. Uma tag personalizada é uma tag usada em seu HTML que não é uma dessas tags .

Parece que a linha schemas: [ CUSTOM_ELEMENTS_SCHEMA ]precisa ser adicionada a cada componente em que você está usando tags HTML personalizadas.

EDIT: A schemasdeclaração precisa estar em um @NgModuledecorador. O exemplo abaixo mostra um módulo personalizado com um componente personalizado CustomComponentque permite qualquer tag html no modelo html para esse componente.

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

Aqui você pode usar qualquer tag HTML que desejar.

<div class="container">
  <boogey-man></boogey-man>
  <my-minion class="one-eyed">
    <job class="plumber"></job>
  </my-minion>
</div>
Caleb
fonte
Eu tenho um aplicativo muito simples que possui vários componentes em um único módulo. Eu adicionei-lo para meu módulo ... Eu ainda obter erros ...
Nicolas Irisarri
7
Obrigado Caleb. Eu estava recebendo os erros ao executar um teste simples. Eu percebi isso ... Não estava adicionando o CUSTOM_ELEMENTS_SCHEMAmódulo falso no meu teste de unidade. Assim que eu fiz isso, ele parou de reclamar.
Nicolas Irisarri
1
Existe uma maneira de definir elementos personalizados que são permitidos? O uso CUSTOM_ELEMENTS_SCHEMApode levar a erros difíceis de encontrar, mas eu gostaria de usar nomes de elementos personalizados para ng-contentseções em meus controles sem que esses nomes de elementos específicos causem erros e sem criar componentes para eles que seriam apenas conteúdo de conteúdo ...
Jason Goemaat
1
@Caleb, você pode fornecer um exemplo rápido de código do que você quer dizer? Parece que a linha schemas: [ CUSTOM_ELEMENTS_SCHEMA ]precisa ser adicionada a cada componente em que você está usando tags HTML ? Parece que o Componentdecorador não está aceitando um schemasparâmetro.
Danny Bullis
2
Hey @DannyBullis, em vez do Componentdecorador, é encontrado no NgModuledecorador. Você precisará criar um módulo para esse componente e, em seguida, poderá especificar o esquema lá. Link para documentos e um exemplo.
Caleb
85

Isso é corrigido por:

a) adicionando schemas: [ CUSTOM_ELEMENTS_SCHEMA ]a cada componente ou

b) adicionando

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

e

schemas: [
  CUSTOM_ELEMENTS_SCHEMA
],

para o seu módulo.

Raphael Hippe
fonte
7
não esqueça de declarar ... está localizado em @ angular / core. Algo como isso deve caber:import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
rlasjunies
Esta publicação pode ajudar no procedimento a seguir: medium.com/google-developer-experts/…
Carlos E
1
adicionando esquemas: [CUSTOM_ELEMENTS_SCHEMA] a TODOS os componentes, fez o truque! Obrigado!
Pedro Ferreira
esquemas não existem no angular 9
Renil Babu 04/07
37

Isso também pode surgir ao executar testes de unidade, se você estiver testando um componente com elementos personalizados. Nesse caso, custom_elements_schema precisa ser incluído no testingModule que é configurado no início do arquivo .spec.ts para esse componente. Aqui está um exemplo de como a instalação do header.component.spec.ts começaria:

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
fonte
1
Obrigado! Demorei muito # & @% para encontrar isso.
eflat 18/03
23

Adicione o seguinte @NgModule({})em 'app.module.ts':

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

e depois

schemas: [
    CUSTOM_ELEMENTS_SCHEMA
]

Seu 'app.module.ts' deve ficar assim:

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

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

export class AppModule { }
Negin
fonte
2
mas agora todo o seu aplicativo está permitindo tags personalizadas.
EE33
10

Também não funcionou para mim. eu mudei

CUSTOM_ELEMENTS_SCHEMA

para

NO_ERRORS_SCHEMA

sugerida neste artigo: https://scotch.io/tutorials/angular-2-transclusion-using-ng-content

Agora funciona.

Martin Cremer
fonte
Agradável! Funcionou para mim. Eu queria adicionar elementos XML no meu componente HTML e estava recebendo erros. Muito obrigado
Celso Soares
estava servindo elementos angulares dentro elementos angulares dentro elementos angulares (Angular 8) adicionando CUSTOM_ELEMENTS_SCHEMAnão ajuda, mas NO_ERRORS_SCHEMAfez o truque e todo o assentamento de elementos angulares autônomos agora funciona como um encanto
Yogi
Isso funcionou para mim TestBed. O elemento estava funcionando bem, mas o teste estava falhando. Adicionado schemas: [NO_ERRORS_SCHEMA], e está tudo bem.
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 precisa ser exportado

dashboard.module.ts
import AccountModuleno módulo onde queremos usar<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() {}
}

Não sou obrigado a importar e usar CUSTOM_ELEMENTS_SCHEMA.
no entanto, não está funcionando quando o dashboard.module está carregado preguiçosamente.
Ao usar CUSTOM_ELEMENTS_SCHEMAem caso de carregamento lento, o erro é suprimido, mas o componente não é adicionado ao dom.

Uma corrida
fonte
idem +1 não mais erro, mas nenhuma atualização dom mais, esta solução alternativa para tentar tornar o trabalho desses seletores com '-' é #### !!! && U * $
user1568220
1
Muito obrigado, depois de uma semana, eu descobri que ele não pode funcionar com carregamento lento no iônico
Amr
1
@Arun - sua solução é 100% exato, 1) necessidade de adicionar à exportação e 2) não há necessidade de custom_elements_schema
Ashwin
Eu tive o mesmo erro e configurei meus componentes em cada módulo onde eu precisava na cláusula de declarações. Não usei CUSTOM_ELEMENTS_SCHEMA e trabalhei.
David
6

Com componentes contendo material angular, ocorreu um erro semelhante nos meus testes de unidade. Conforme a resposta de @Dan Stirling-Talbert acima, adicionei isso ao meu arquivo .spec componente e o erro foi eliminado dos meus testes de unidade.

Import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'

Em seguida, adicione o esquema na instrução beforeEach () gerada:

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

Meu erro no Karma foi: Se 'mat-panel-title' for um componente da Web, adicione 'CUSTOM_ELEMENTS_SCHEMA' ao '@ NgModule.schemas' deste componente para suprimir esta mensagem.

T. Bulford
fonte
4

Basta ler este post e de acordo com os 2 documentos angulares:

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.

Portanto, caso alguém encontre esse problema, depois de adicionar CUSTOM_ELEMENTS_SCHEMA ao seu NgModule, verifique se qualquer novo elemento personalizado usado possui um 'traço' em seu nome, por exemplo. ou etc.

Hugo 1005
fonte
1
Um traço no nome? Por que impor uma convenção tão estúpida?
Meryan
Só me deparei com isso quando comecei a usar o carregamento lento no Ionic3 e apenas quando tento criar para a web. Poderia postar o link para os documentos mencionados. Obrigado.
Meryan
3

Este post é bastante longo e fornece uma explicação mais detalhada do problema.

O problema (no meu caso) surge quando você tem projeção de conteúdo com vários slots

Veja também projeção de conteúdo para mais informações.

Por exemplo, se você tem um componente que se parece com isso:

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

arquivo ts:

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

E você deseja usá-lo como:

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


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

E então você obtém erros de análise de modelo que não é um componente Angular conhecido e, na verdade, não é - é apenas uma referência a um conteúdo ng em seu componente:

E a solução mais simples é adicionar

schemas: [
    CUSTOM_ELEMENTS_SCHEMA
],

... para seu app.module.ts


Mas existe uma abordagem fácil e limpa para esse problema - em vez de usar <my-component-header>para inserir html no slot - você pode usar um nome de classe para esta tarefa como esta:

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

E você deseja usá-lo como:

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

Então ... não há mais componentes que não existem, portanto não há problemas, erros, necessidade de CUSTOM_ELEMENTS_SCHEMA no app.module.ts

Portanto, se você era como eu e não queria adicionar CUSTOM_ELEMENTS_SCHEMA ao módulo - usar seu componente dessa maneira não gera erros e é mais claro.

Para mais informações sobre este problema - https://github.com/angular/angular/issues/11251

Para obter mais informações sobre projeção de conteúdo angular - https://blog.angular-university.io/angular-ng-content/

Você também pode ver https://scotch.io/tutorials/angular-2-transclusion-using-ng-content

Combinar
fonte
1
era exatamente isso que eu procurava, obrigado por compartilhar!
Romeouald
1

Gostaria de adicionar mais uma informação, pois a resposta aceita acima não corrigiu completamente meus erros.

No meu cenário, eu tenho um componente pai, que contém um componente filho. E esse componente filho também contém outro componente.

Portanto, o arquivo de especificação do meu componente pai precisa ter a declaração do componente filho, assim como o componente da criança. Isso finalmente resolveu o problema para mim.

ganders
fonte
1

Eu acho que você está usando um módulo personalizado. Você pode tentar o seguinte. Você precisa adicionar o seguinte ao arquivo your-module.module.ts :

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

Isso não funcionou para mim (usando o 2.0.0). O que funcionou para mim foi importar o RouterTestingModule.

Eu resolvi isso importando RouterTestingModule no arquivo de especificações.

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

  beforeEach(() => {

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

    });
HMagdy
fonte
0

Para mim, eu precisava olhar para:

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

Isso significa que seu componente não está incluído no app.module.ts. Verifique se ele foi importado e incluído na declarationsseção.

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

Acabei de importar ClarityModulee resolveu todos os problemas. De uma chance!

import { ClarityModule } from 'clarity-angular';

Além disso, inclua o módulo nas importações.

imports: [ ClarityModule ],

Ishani
fonte
Ei, Ishani. Você também pode adicionar uma explicação sobre por que funciona?
f.khantsis 30/03
Se visitarmos a documentação CUSTOM_ELEMENTS_SCHEMA, em angular.io/api/core/CUSTOM_ELEMENTS_SCHEMA , descobriremos que CUSTOM_ELEMENTS_SCHEMA permite que o NgModule contenha elementos não angulares com maiúsculas e minúsculas (-) {semelhante a este cenário}. O Módulo Clarity, quando importado, inclui todos os ícones clr, etc. por padrão, e também podemos usar outras funcionalidades do módulo Clarity.
Ishani 31/03
Isso é irrelevante para o problema aqui. Como você resolve isso importando o módulo de clareza? @Ishani
HelloWorld
se você ler a declaração do problema, o Angular não poderá identificar clr-header. O mesmo erro ocorre para clr-iconoutros. Como mencionei no meu comentário anterior, o módulo Clarity contém esses por padrão. Espero que tenha respondido sua pergunta.
Ishani 04/04
0

resolveu esse problema no arquivo /app/app.module.ts

importe seu componente e declare-o

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

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

Você usou o webpack ... se sim, instale

angular2-template-loader

e coloca

test: /\.ts$/,
   loaders: ['awesome-typescript-loader', 'angular2-template-loader']
Imanullah
fonte
Não consigo localizar os testes padrão que foram criados pelo componente que gera ng e obtive o mesmo erro. Nada a partir deste tópico não foi útil :( eu tirar um erro apenas quando eu tinha sido comentou componentes especificação arquivos :(
Nesquik27
Entendi direito que tags personalizadas estavam trabalhando apenas com angular abaixo da v2 ?! Fui verificar algo no youtube e eu estou tentando testar meu código de v2 no ambiente v4
Nesquik27