web-dev-qa-db-fra.com

Utilisation de Renderer dans Angular 4

Je comprends pourquoi il est préférable d'utiliser le rendu au lieu de manipuler directement le DOM dans les projets Angular2. Cependant, j'ai désinstallé, effacé le cache, réinstallé Node, TypeScript et Angular-CLI plusieurs fois et j'obtiens toujours une erreur lorsque j'essaie d'injecter le Renderer.

import { Injectable, Renderer2 } from '@angular/core';
constructor(private renderer: Renderer2) {}

__zone_symbol__message: "Aucun fournisseur pour Renderer2!"

__zone_symbol__stack: "Error↵ at Error.ZoneAwareError

Quelqu'un at-il une idée de ce que je fais mal?

14

Mise à jour:

@Injectable()
class MyService {
  private renderer: Renderer2;

  constructor(rendererFactory: RendererFactory2) {
    this.renderer = rendererFactory.createRenderer(null, null);
  }
}

Voir plus à ce sujet ici: https://github.com/angular/angular/issues/17824#issuecomment-351961146

Version précédente:

Selon vos importations

import { Injectable, Renderer2 } from '@angular/core'

je soupçonne que vous essayez d'injecter Renderer2 dans votre classe de service. Ça ne marchera pas. Vous ne pouvez pas injecter Renderer2 en service. Il devrait fonctionner pour les composants et services fournis dans le composant.

Nous pouvons jeter un œil au code source https://github.com/angular/angular/blob/4.0.1/packages/core/src/view/provider.ts#L363-L37

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

il vérifie uniquement dans l'arborescence des injecteurs d'éléments. Et il n'y a aucun autre endroit où ce jeton peut être fourni

Vous devez donc passer Renderer2 du composant au service lorsque vous appelez une méthode de service https://github.com/angular/angular/issues/17824#issuecomment-311986129

ou vous pouvez fournir un service au sein du composant

@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) {}
}
27
yurzui

Vous ne pouvez pas injecter Renderer2, Mais nous pouvons exécuter RendererFactory2 Pour obtenir l'instance de Renderer2 Dans le service @Injectable(). Il y a la façon dont Angular utiliser en interne chez les webworkers, par exemple.

J'ai résolu le problème avec le code ci-dessous:

import { Renderer2, RendererFactory2 } from '@angular/core';

@Injectable()
class Service {
    private renderer: Renderer2;

    constructor(rendererFactory: RendererFactory2) {
        this.renderer = rendererFactory.createRenderer(null, null);
    }
}

Les paramètres de la méthode RendererFactory2.createRenderer Sont:

  • hostElement avec le type any
  • type avec le type RendererType2|null

Vous pouvez voir que les paramètres (null, null) Sont ici: https://github.com/angular/angular/blob/e3140ae888ac4037a5f119efaec7b1eaf8726286/packages/core/src/render/api.ts#L129

13
Eugene Gavrilov