CUSTOM_ELEMENTS_SCHEMA agregado a NgModule.schemas aún muestra Error

137

Acabo de actualizar de Angular 2 rc4 a rc6 y tengo problemas para hacerlo.

Veo el siguiente error en mi consola:

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

Aquí está mi componente de encabezado:

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

Aquí está mi módulo de encabezado:

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

Creé un módulo contenedor llamado módulo util que importa el HeaderModule:

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

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

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

El cual finalmente es importado por el 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 { }

Según tengo entendido, estoy siguiendo las instrucciones del mensaje de error usando SCHEMA para eliminar el error. Pero parece que no funciona. ¿Qué estoy haciendo mal? (Espero que no sea nada obvio que no veo en este momento. He pasado las últimas 6 horas actualizando a esta versión ...)

Raphael Hippe
fuente
1
Si lo agrega a su AppModuletodavía tiene que agregarlo a su componente?
Alessandro Resta
1
lo mismo aquí, para mí simplemente agregar "esquemas: [CUSTOM_ELEMENTS_SCHEMA]" funcionó a las mil maravillas. Gracias :)
AIon
3
Sería útil si agregara su "Solución" como respuesta a esta pregunta, de modo que sea claro para los demás que encuentren su pregunta exactamente cómo pueden beneficiarse al usar su solución:]
Danny Bullis

Respuestas:

97

Solo quería agregar un poco más sobre esto.

Con la nueva versión final angular 2.0.0 (14 de septiembre de 2016), si usa etiquetas html personalizadas, lo informará Template parse errors. Una etiqueta personalizada es una etiqueta que usa en su HTML que no es una de estas etiquetas .

Parece que la línea schemas: [ CUSTOM_ELEMENTS_SCHEMA ]debe agregarse a cada componente donde está utilizando etiquetas HTML personalizadas.

EDITAR: La schemasdeclaración debe estar en un @NgModuledecorador. El siguiente ejemplo muestra un módulo personalizado con un componente personalizado CustomComponentque permite cualquier etiqueta html en la plantilla html para ese 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

Aquí puede usar cualquier etiqueta HTML que desee.

<div class="container">
  <boogey-man></boogey-man>
  <my-minion class="one-eyed">
    <job class="plumber"></job>
  </my-minion>
</div>
Caleb
fuente
Tengo una aplicación muy simple que tiene múltiples componentes en un solo módulo. Lo he agregado a mi módulo ... Todavía recibo errores ...
Nicolas Irisarri
77
Gracias Caleb Recibía los errores al ejecutar una prueba simple. Sin embargo, lo descubrí ... No estaba agregando el CUSTOM_ELEMENTS_SCHEMAmódulo falso de prueba de mi unidad. Tan pronto como hice eso, dejó de quejarse.
Nicolas Irisarri
1
¿Hay alguna manera de definir elementos personalizados que estén permitidos? El uso CUSTOM_ELEMENTS_SCHEMApodría dar lugar a errores que son difíciles de encontrar, pero me gustaría usar nombres de elementos personalizados para las ng-contentsecciones en mis controles sin que esos nombres de elementos específicos causen errores y sin crear componentes para ellos que solo serían ng-content ...
Jason Goemaat
1
@Caleb, ¿puede proporcionar un ejemplo de código rápido de lo que quiere decir con Parece que la línea schemas: [ CUSTOM_ELEMENTS_SCHEMA ]debe agregarse a cada componente donde está utilizando etiquetas HTML ? Parece que el Componentdecorador no acepta un schemasparámetro.
Danny Bullis
2
Hola @DannyBullis, en lugar del Componentdecorador, se encuentra en el NgModuledecorador. Deberá crear un módulo para ese componente y luego puede especificar el esquema allí. Enlace a documentos y un ejemplo.
Caleb
85

Esto se soluciona mediante:

a) agregando schemas: [ CUSTOM_ELEMENTS_SCHEMA ]a cada componente o

b) agregando

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

y

schemas: [
  CUSTOM_ELEMENTS_SCHEMA
],

a su módulo

Raphael Hippe
fuente
77
no olvides declararlo ... está ubicado en @ angular / core. Algo así debe ajustarse:import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
rlasjunies
Esta publicación podría ayudar con el procedimiento a seguir: medium.com/google-developer-experts/…
Carlos E
1
agregando esquemas: [CUSTOM_ELEMENTS_SCHEMA] a CADA componente, ¡funcionó! ¡Gracias!
Pedro Ferreira
esquemas no existen en angular 9
Renil Babu
37

Esto también puede aparecer al ejecutar pruebas unitarias si está probando un componente con elementos personalizados. En ese caso, custom_elements_schema debe agregarse al testingModule que se configura al comienzo del archivo .spec.ts para ese componente. Aquí hay un ejemplo de cómo comenzaría la configuración 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
fuente
1
¡Gracias! Me tomó demasiado tiempo # & @% para encontrar esto.
Elat
23

Agregue lo siguiente @NgModule({})en 'app.module.ts':

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

y entonces

schemas: [
    CUSTOM_ELEMENTS_SCHEMA
]

Su 'app.module.ts' debería verse así:

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

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

export class AppModule { }
Negin
fuente
2
pero ahora toda su aplicación permite etiquetas personalizadas.
EE33
10

A mí tampoco me funcionó. Cambié

CUSTOM_ELEMENTS_SCHEMA

para

NO_ERRORS_SCHEMA

que se sugirió en este artículo: https://scotch.io/tutorials/angular-2-transclusion-using-ng-content

Ahora funciona.

Martin Cremer
fuente
¡Agradable! Funcionó para mi. Quería agregar elementos XML en mi componente HTML y recibía errores. Muchas gracias
Celso Soares
estaba sirviendo elementos angulares dentro de elementos angulares dentro de elementos angulares (Angular 8) agregar CUSTOM_ELEMENTS_SCHEMAno ayudó pero NO_ERRORS_SCHEMAhizo el truco y toda la anidación de elementos angulares independientes ahora funciona como un encanto
Yogi
Esto funcionó para mí TestBed. El elemento funcionaba bien pero la prueba estaba fallando. Agregado schemas: [NO_ERRORS_SCHEMA], y todo está 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 necesita ser exportado

dashboard.module.ts
import AccountModuleen el módulo donde 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() {}
}

No estoy obligado a importar y usar CUSTOM_ELEMENTS_SCHEMA.
sin embargo, no funciona cuando dashboard.module tiene una carga lenta.
Cuando se usa CUSTOM_ELEMENTS_SCHEMAen caso de carga diferida, el error se suprime pero el componente no se agrega a dom.

Arun
fuente
idem +1 no más error, pero ya no hay actualización de dom, esta solución para tratar de hacer funcionar esos selectores con '-' es #### !!! && ù * $
user1568220
1
Muchas gracias, después de una semana, descubrí que no puede funcionar con carga perezosa en iónico
Amr.Ayoub
1
@Arun: su solución es 100% precisa, 1) necesita agregar a la exportación y 2) no necesita custom_elements_schema
Ashwin
Tuve el mismo error y configuré mis componentes en cada módulo donde lo necesitaba en las declaraciones clausule. No utilicé CUSTOM_ELEMENTS_SCHEMA y trabajé.
David
6

Con los componentes que contienen material angular, se produjo un error similar con las pruebas de mi unidad. Según la respuesta anterior de @Dan Stirling-Talbert, agregué esto a mi archivo .spec de componente y el error se borró de mis pruebas unitarias.

Import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'

Luego agregue el esquema en la declaración generada beforeEach ():

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

Mi error de Karma fue: si 'mat-panel-title' es un Componente Web, agregue 'CUSTOM_ELEMENTS_SCHEMA' a '@ NgModule.schemas' de este componente para suprimir este mensaje.

T. Bulford
fuente
4

Solo lea esta publicación y de acuerdo con los documentos angulares 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.

Entonces, en caso de que alguien se encuentre con este problema, una vez que haya agregado CUSTOM_ELEMENTS_SCHEMA a su NgModule, asegúrese de que cualquier elemento personalizado nuevo que use tenga un 'guión' en su nombre, por ejemplo. o etc.

Hugo 1005
fuente
1
¿Un guión en el nombre? ¿Por qué imponer una convención tan estúpida?
Meryan
Solo me encontré con esto cuando comencé a usar la carga diferida en Ionic3 y solo cuando trato de construir para la web. Podría publicar el enlace a los documentos que menciona. Gracias.
Meryan
3

Esta es una publicación bastante larga y ofrece una explicación más detallada del problema.

El problema (en mi caso) surge cuando tienes Proyección de contenido de múltiples ranuras

Vea también la proyección de contenido para más información.

Por ejemplo, si tiene un componente que se ve así:

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

archivo ts:

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

Y quieres usarlo 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>

Y luego obtiene errores de análisis de plantilla que no es un componente angular conocido y, de hecho, no lo es; es solo una referencia a un contenido ng en su componente:

Y luego la solución más simple es agregar

schemas: [
    CUSTOM_ELEMENTS_SCHEMA
],

... a tu app.module.ts


Pero hay un enfoque fácil y limpio para este problema: en lugar de usar <my-component-header>para insertar html en la ranura, puede usar un nombre de clase para esta tarea de esta manera:

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

Y quieres usarlo 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>

Entonces ... no más componentes que no existen, por lo que no hay problemas en eso, no hay errores, no es necesario para CUSTOM_ELEMENTS_SCHEMA en app.module.ts

Entonces, si fueras como yo y no quisieras agregar CUSTOM_ELEMENTS_SCHEMA al módulo, usar tu componente de esta manera no genera errores y es más claro.

Para obtener más información sobre este problema: https://github.com/angular/angular/issues/11251

Para obtener más información sobre la proyección de contenido angular: https://blog.angular-university.io/angular-ng-content/

También puede ver https://scotch.io/tutorials/angular-2-transclusion-using-ng-content

Combinar
fuente
1
esto era justo lo que estaba buscando, ¡gracias por compartir!
romeouald
1

Me gustaría agregar una información adicional ya que la respuesta aceptada arriba no solucionó mis errores por completo.

En mi escenario, tengo un componente primario, que contiene un componente secundario. Y ese componente hijo también contiene otro componente.

Por lo tanto, el archivo de especificaciones del componente principal debe tener la declaración del componente secundario, ASÍ COMO EL COMPONENTE DEL NIÑO DEL NIÑO. Eso finalmente solucionó el problema para mí.

gaders
fuente
1

Creo que estás usando un módulo personalizado. Puedes probar lo siguiente. Debe agregar lo siguiente al archivo your-module.module.ts :

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

Eso no funcionó para mí (usando 2.0.0). Lo que funcionó para mí fue importar RouterTestingModule en su lugar.

Resolví esto importando RouterTestingModule en el archivo de especificaciones.

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

  beforeEach(() => {

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

    });
HMagdy
fuente
0

Para mí, necesitaba mirar:

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

Esto significa que su componente no está incluido en el app.module.ts. Asegúrese de que se importe y luego se incluya en la declarationssección.

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

Acabo de importar ClarityModuley resolvió todos los problemas. ¡Darle una oportunidad!

import { ClarityModule } from 'clarity-angular';

Además, incluya el módulo en las importaciones.

imports: [ ClarityModule ],

Ishani
fuente
Hola Ishani ¿Pueden agregar también una explicación de por qué funciona?
f.khantsis
Si visitamos la documentación para CUSTOM_ELEMENTS_SCHEMA, en angular.io/api/core/CUSTOM_ELEMENTS_SCHEMA , encontraremos que CUSTOM_ELEMENTS_SCHEMA permite que NgModule contenga elementos no angulares con un guión (-) {similar a este escenario}. Clarity Module cuando se importa incluye todos los iconos clr, etc. de forma predeterminada y también podemos usar otras funcionalidades del módulo de claridad.
Ishani
Esto es irrelevante para el problema aquí. ¿Cómo lo resuelves importando el módulo de claridad? @Ishani
HelloWorld
si lee el enunciado del problema, Angular no puede identificarlo clr-header. Se produce el mismo error clr-icony otros. Como mencioné en mi comentario anterior, el módulo Clarity contiene estos por defecto. Espero que haya respondido tu pregunta.
Ishani
0

resolvió este problema en el archivo /app/app.module.ts

importa tu componente y declaralo

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

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

¿Usó el paquete web? Si es así, instale

angular2-template-loader

y ponlo

test: /\.ts$/,
   loaders: ['awesome-typescript-loader', 'angular2-template-loader']
Imanullah
fuente
No puedo enrutar las pruebas predeterminadas creadas por el componente que genera ng g y obtuve el mismo error. Nada de este tema no fue útil :(
Quito
¿Entiendo bien que las etiquetas personalizadas funcionaban solo con angular debajo de v2? He comprobado algo en YouTube y estoy tratando de probar mi código desde v2 en entorno v4
Nesquik27