typescript 在 Angular 4 中使用渲染器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43070308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 04:23:30  来源:igfitidea点击:

Using Renderer in Angular 4

angulartypescriptangular-cli

提问by Michael_Cloudbusting

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, Typescript and the Angular-CLI several times and I still get an error when trying to inject the Renderer.

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

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

__zone_symbol__message: "No provider for Renderer2!"

__zone_symbol__stack:"Error? at Error.ZoneAwareError

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

__zone_symbol__stack:"错误?在 Error.ZoneAwareError

Does anyone have any ideas what I am doing wrong?

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

回答by yurzui

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

在此处查看更多信息: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 Renderer2in your service class. It won't work. You can't inject Renderer2in service. It should work for components and services that are provided within component.

我怀疑您正试图注入Renderer2您的服务类。它不会工作。你不能注入Renderer2服务。它应该适用于组件内提供的组件和服务。

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

我们可以看一下源码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 Renderer2from component to service when you're calling some service method https://github.com/angular/angular/issues/17824#issuecomment-311986129

因此Renderer2,当您调用某些服务方法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) {}
}

回答by Eugene Gavrilov

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

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

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.createRenderermethod are:

RendererFactory2.createRenderer方法参数为:

  • hostElementwith type any
  • typewith type RendererType2|null
  • hostElement带类型 any
  • 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

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