Entiendo por qué es mejor usar el renderizador en lugar de manipular directamente el DOM en los proyectos de Angular2. Sin embargo, he desinstalado, borrado el caché, reinstalado Node, Typescript y Angular-CLI varias veces y sigo recibiendo un error cuando intento inyectar el Renderer.
import { Injectable, Renderer2 } from '@angular/core'; constructor(private renderer: Renderer2) {}__zone_symbol__message: "¡No hay proveedor para Renderer2!"
__zone_symbol__stack:"Error↵ en Error.ZoneAwareError
¿Alguien tiene alguna idea de lo que estoy haciendo mal?
Actualizar:
@Injectable() class MyService { private renderer: Renderer2; constructor(rendererFactory: RendererFactory2) { this.renderer = rendererFactory.createRenderer(null, null); } }Vea más sobre esto aquí: https://github.com/angular/angular/issues/17824#issuecomment-351961146
Versión previa:
Según sus importaciones
import { Injectable, Renderer2 } from '@angular/core' Sospecho que está intentando inyectar Renderer2 en su clase de servicio. No funcionará. No puede inyectar Renderer2 en servicio. Debería funcionar para los componentes y servicios que se proporcionan dentro del componente.
Podemos echar un vistazo al código fuente https://github.com/angular/angular/blob/4.0.1/packages/core/src/view/provider.ts#L363-L373
while (view) { if (elDef) { switch (tokenKey) { case RendererV1TokenKey: { const compView = findCompView(view, elDef, allowPrivateServices); return createRendererV1(compView); } case Renderer2TokenKey: { const compView = findCompView(view, elDef, allowPrivateServices); return compView.renderer; }comprueba solo dentro del árbol del inyector de elementos. Y no hay otros lugares donde se pueda proporcionar este token
Por lo tanto, debe pasar Renderer2 del componente al servicio cuando llama a algún método de servicio https://github.com/angular/angular/issues/17824#issuecomment-311986129
o puede proporcionar servicio dentro del componente
@Injectable() export class Service { constructor(private r: Renderer2) {} } @Component({ selector: 'my-app', templateUrl: `./app.component.html`, providers: [Service] }) export class AppComponent { constructor(private service: Service) {} }No puede inyectar Renderer2 , pero podemos ejecutar RendererFactory2 para obtener la instancia de Renderer2 dentro del servicio @Injectable() . Existe la forma en que Angular usa internamente en webworkers, por ejemplo.
He resuelto el problema con el siguiente código:
import { Renderer2, RendererFactory2 } from '@angular/core'; @Injectable() class Service { private renderer: Renderer2; constructor(rendererFactory: RendererFactory2) { this.renderer = rendererFactory.createRenderer(null, null); } } Los parámetros del método RendererFactory2.createRenderer son:
hostElement con any tipotype con tipo RendererType2|null Puede ver que los parámetros (null, null) están aquí: https://github.com/angular/angular/blob/e3140ae888ac4037a5f119efaec7b1eaf8726286/packages/core/src/render/api.ts#L129