typescript 服务:Renderer2 没有提供者
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44989666/
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
Service: No provider for Renderer2
提问by BeetleJuice
Angular 4.2
with Typescript 2.3
Angular 4.2
和 Typescript 2.3
I am refactoring a service that is responsible for creating a new script tag and adding it to the document.
我正在重构一个负责创建新脚本标记并将其添加到文档的服务。
Here is the old code:
这是旧代码:
loadScript(src:string){
const script = document.createElement('script');
document.body.appendChild(script);
script.src = src;
}
Now, I'd like to use the Renderer2
to avoid doing direct DOM manipulation. So I've injected what I need in my service and updated the code:
现在,我想使用Renderer2
避免进行直接的 DOM 操作。所以我在我的服务中注入了我需要的东西并更新了代码:
constructor(private renderer:Renderer2, @Inject(DOCUMENT) private document){}
loadScript(src:string){
const script = this.renderer.createElement('script');
this.renderer.appendChild(this.document.body,script);
script.src = src;
}
However, I run into this error:
但是,我遇到了这个错误:
Error: no provider for Renderer2!
错误:Renderer2 没有提供程序!
The service belongs to a CoreModule
whose only import is CommonModule
from @angular/common
该服务属于CoreModule
其唯一导入CommonModule
来自@angular/common
This plunkrdemonstrates the problem
这个 plunkr演示了这个问题
回答by Eugene Gavrilov
Possibly duplicating with Using Renderer in Angular 4
可能与在 Angular 4 中使用渲染器重复
You cannot inject Renderer2
, but we can run RendererFactory2
to get Renderer2
instance inside @Injectable()
service.
There are two different ways of solving this issue.
您不能注入Renderer2
,但我们可以运行RendererFactory2
以获取服务Renderer2
内的实例@Injectable()
。有两种不同的方法可以解决这个问题。
Get an instance of Renderer2 inside Service
在 Service 中获取 Renderer2 的实例
There is the way which Angular using internally in webworkers, for example. I've solved the problem with the code below:
例如,Angular 在 webworkers 内部使用的方式。我已经用下面的代码解决了这个问题:
import { Injectable, Renderer2, RendererFactory2 } from '@angular/core';
@Injectable()
class Service {
private renderer: Renderer2;
constructor(rendererFactory: RendererFactory2) {
this.renderer = rendererFactory.createRenderer(null, null);
}
}
In your particular case, it will be
在您的特定情况下,它将是
@Injectable()
class Service {
private renderer: Renderer2;
constructor(rendererFactory: RendererFactory2, @Inject(DOCUMENT) private document){
this.renderer = rendererFactory.createRenderer(null, null);
}
loadScript(src:string){
const script = this.renderer.createElement('script');
this.renderer.appendChild(this.document.body,script);
script.src = src;
}
}
Parameters of RendererFactory2.createRenderer
method are:
RendererFactory2.createRenderer
方法参数为:
hostElement
with typeany
type
with typeRendererType2|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
Pass Renderer2 from component
从组件传递 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;
}
}
回答by yurzui
You can initialize service with an instance of Renderer2
in root component
您可以使用Renderer2
根组件中的实例初始化服务
@Injectable()
class MyService {
renderer : Renderer2;
}
...
class App {
name:string;
constructor(service: MyService, renderer: Renderer2) {
service.renderer = renderer;
}
}
See also
也可以看看
回答by Florian
I tried to implement this using render2, but in a service - leading to 'StaticInjectorError(AppModule)[Renderer2]'-Error, as injecting Renderer2-Instance seems to not be possible. Solution was to inject RendererFactory2 and manullay create the reference within the service, like:
我尝试使用 render2 来实现这一点,但在服务中 - 导致 'StaticInjectorError(AppModule)[Renderer2]'-Error,因为注入 Renderer2-Instance 似乎是不可能的。解决方案是注入 RendererFactory2 和 manullay 在服务中创建引用,例如:
@Injectable({
providedIn: 'root'
})
export class FgRendererService {
/** Reference to render-instance */
public renderer: Renderer2;
/** CONSTRUCTOR */
constructor(
private _renderer: RendererFactory2
) {
this.renderer = _renderer.createRenderer(null, null);
}
/** Add class to body-tag */
addBodyClass( classToAdd: string ): void {
this.renderer.addClass( document.body, classToAdd );
}
/** Remove class from body-tag */
removeBodyClass( classToRemove: string ): void {
this.renderer.removeClass( document.body, classToRemove );
}
}