是否可以在服务中使用渲染器或仅在组件中使用?
如果我将渲染器注入服务器,我会收到错误,即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');
}
}
答案 0 :(得分:10)
可能与Using Renderer in Angular 4
重复您无法注入Renderer2
,但我们可以运行RendererFactory2
来获取Renderer2
服务中的@Injectable()
实例。
有两种不同的解决方法issue。
例如,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
// 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,并将它与其他真正的数据服务分开。