渲染器不能用于服务?

时间:2016-01-10 20:26:59

标签: angular

是否可以在服务中使用渲染器或仅在组件中使用?

如果我将渲染器注入服务器,我会收到错误,即Renderer提供程序丢失。

请参阅plunker的控制台:

import {Injectable, Component, Renderer, ElementRef} from 'angular2/core';

@Injectable()
class TestService {
  constructor(
    private _renderer: Renderer
    ) {}

  renderElement(elementRef: any) {
    this._renderer.createElement(elementRef.nativeElement, 'div');
  }
}

http://plnkr.co/edit/e8qlznCVbvZnXbLTk36z?p=preview

2 个答案:

答案 0 :(得分:10)

可能与Using Renderer in Angular 4

重复

您无法注入Renderer2,但我们可以运行RendererFactory2来获取Renderer2服务中的@Injectable()实例。 有两种不同的解决方法issue

在服务

中获取Renderer2的实例

例如,Angular在网络工作者内部使用的方式。 我用下面的代码解决了这个问题:

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

从组件

传递Renderer2
// declare public property in your service
@Injectable()
class Service {
  renderer: Renderer;
}

// pass renderer to service in your component file
class App {
  name:string;
  constructor(service: Service, renderer: Renderer2) {
      service.renderer = renderer;
  }
}

答案 1 :(得分:4)

是的,就像Eric说的那样,你可以将它从实际的组件传递给服务,它会起作用。

但是,呈现对象的责任是组件,而不是服务,服务是为了处理业务逻辑(主要检索数据,取决于您的应用程序)。

如果您改变演示文稿框架/库或任何与演示相关的内容,那么整个想法是您可以重用整个服务层。如果您这样做,您可以将您的服务与您的演示文稿相结合,以后更难做出改变。

如果要在组件之间重用渲染逻辑,我将使用逻辑创建父抽象类并使用Component扩展它,子组件将注入渲染器并将其传递给父类。应该调用父构造函数的super()方法。

至少你可以像建议的解决方案那样创建一个@Injectable对象,但是把它称为SomethingRenderer而不是Service,并将它与其他真正的数据服务分开。