【问题标题】:Using Renderer in Angular 4在 Angular 4 中使用渲染器
【发布时间】:2017-08-21 13:42:59
【问题描述】:

我理解为什么在 Angular2 项目中使用渲染器而不是直接操作 DOM 更好。但是,我已经多次卸载、清除缓存、重新安装 Node、Typescript 和 Angular-CLI,但在尝试注入 Renderer 时仍然出现错误。

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

__zone_symbol__message:“没有 Renderer2 的提供者!”

__zone_symbol__stack:"Error↵ at Error.ZoneAwareError

有人知道我做错了什么吗?

【问题讨论】:

  • 构造函数来自哪个类?它是组件还是指令?是服务吗?

标签: angular typescript angular-cli


【解决方案1】:

更新:

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

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

在此处查看更多信息: https://github.com/angular/angular/issues/17824#issuecomment-351961146

以前的版本:

根据您的进口情况

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

我怀疑您正试图在您的服务类中注入 Renderer2。它行不通。您不能在服务中注入Renderer2。它应该适用于组件内提供的组件和服务。

我们可以看一下源码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;
      }

它只在元素注入器树中检查。而且没有其他地方可以提供这个token

所以当你调用一些服务方法https://github.com/angular/angular/issues/17824#issuecomment-311986129时,你必须将Renderer2从组件传递到服务。

或者你可以在组件内提供服务

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

【讨论】:

  • 很有趣
  • 伙计,这个答案拯救了我整个晚上。
【解决方案2】:

您不能注入Renderer2,但我们可以运行RendererFactory2 以在@Injectable() 服务中获取Renderer2 实例。 例如,Angular 在 webworkers 内部使用的方式。

我已经用下面的代码解决了这个问题:

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

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

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

RendererFactory2.createRenderer方法的参数是:

  • hostElement 类型为 any
  • type 类型为 RendererType2|null

可以看到(null, null)参数在这里: https://github.com/angular/angular/blob/e3140ae888ac4037a5f119efaec7b1eaf8726286/packages/core/src/render/api.ts#L129

【讨论】:

  • @Eugene.thanks for answer.may我知道为什么不能注入Renderer2吗?由于 RendererFactory2 和 Renderer2 都是类所以问
猜你喜欢
  • 2018-03-21
  • 2017-12-04
  • 1970-01-01
  • 1970-01-01
  • 2018-01-22
  • 1970-01-01
  • 2018-01-04
  • 1970-01-01
  • 2018-05-08
相关资源
最近更新 更多