Using Renderer in Angular 4

前端 未结 2 856
你的背包
你的背包 2020-12-24 14:09

I understand why it\'s better to use renderer instead of directly manipulating the DOM in Angular2 projects. However, I have uninstalled, clear cache, reinstalled Node, Type

相关标签:
2条回答
  • 2020-12-24 14:19

    You cannot inject Renderer2, but we can run RendererFactory2 to get Renderer2 instance inside @Injectable() service. There is the way which Angular using internally in webworkers, for example.

    I've solved the problem with the code below:

    import { Renderer2, RendererFactory2 } from '@angular/core';
    
    @Injectable()
    class Service {
        private renderer: Renderer2;
    
        constructor(rendererFactory: RendererFactory2) {
            this.renderer = rendererFactory.createRenderer(null, null);
        }
    }
    

    Parameters of RendererFactory2.createRenderer method are:

    • hostElement with type any
    • type with type RendererType2|null

    You can see that (null, null) parameters are here: https://github.com/angular/angular/blob/e3140ae888ac4037a5f119efaec7b1eaf8726286/packages/core/src/render/api.ts#L129

    0 讨论(0)
  • 2020-12-24 14:23

    Update:

    @Injectable()
    class MyService {
      private renderer: Renderer2;
    
      constructor(rendererFactory: RendererFactory2) {
        this.renderer = rendererFactory.createRenderer(null, null);
      }
    }
    

    See more on this here: https://github.com/angular/angular/issues/17824#issuecomment-351961146

    Previous version:

    According to your imports

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

    i suspect that you're trying to inject Renderer2 in your service class. It won't work. You can't inject Renderer2 in service. It should work for components and services that are provided within component.

    We can take a look at source code 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;
          }
    

    it checks only within element injector tree. And there are no other places when this token can be provided

    So you have to pass Renderer2 from component to service when you're calling some service method https://github.com/angular/angular/issues/17824#issuecomment-311986129

    or you can provide service within component

    @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) {}
    }
    
    0 讨论(0)
提交回复
热议问题