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