![](/img/trans.png)
[英]Angular 5: “NullInjectorError: No provider for Renderer2” on Component
[英]Error: NO Provider for Renderer2! Angular v 4.1.3
我目前正在重構在升級時中斷的一項服務。 我不得不替換browserdomadapter(); 和其他一些不推薦使用的方法。
由於來自2.1ish的各種棄用以及各種重大更改,因此我不得不更改向組件提供此特定服務的方式。 我現在將其直接注入到組件中,這是我推薦的各種答案(通過角度開發人員看到)。
這是錯誤:
問題是我已經在提供程序的組件中引用了注入的服務,如下面的相關代碼所示:
import {Location} from "@angular/common";
import {Component, Injectable, Renderer2, Inject} from "@angular/core";
import {SerieService} from "../shared/services/serie.service";
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { CategoryService } from "../shared/services/category.service";
import {Router, ActivatedRoute, RouterModule, NavigationEnd} from "@angular/router";
import {Http, HttpModule} from "@angular/http";
import {PageviewService} from "../shared/services/pageview.service";
import {Title, DOCUMENT} from '@angular/platform-browser';
import {SeoService} from '../shared/services/seo.service';
@Injectable()
export class Service {
private metaDescription: HTMLElement;
private headElement: HTMLElement;
private robots: HTMLElement;
constructor(@Inject(DOCUMENT) private document: any, private r: Renderer2, private titleService: Title){
this.headElement = this.document.head;
this.metaDescription = this.getOrCreateMetaElement('description');
}
public setMetaDescription(description: string) {
this.r.setAttribute(this.metaDescription, 'content', description)
}
public setMetaRobots(robots: string) {
this.r.setAttribute(this.robots, 'content', robots);
}
public setTitle(newTitle: string) {
this.titleService.setTitle(newTitle + ' | Stareable');
}
private getOrCreateMetaElement(name: string): HTMLElement {
let el: HTMLElement;
el = this.document.querySelector('meta[name=' + name + ']');
if (el === null) {
el = this.document.setAttribute('meta');
this.headElement.appendChild(el);
}
return el;
}
}
@Component({
inputs: ['category'],
templateUrl: './categories.component.html',
styleUrls: ['./categories.component.scss'],
providers: [ Service ]
})
export class CategoriesComponent {
public category: string;
public seriesList: any;
public message: string;
public loading: boolean;
public errorMessage: string;
private slug:string;
constructor (
private service: Service,
private _router: Router,
private _activatedRoute: ActivatedRoute,
private _categoryService: CategoryService,
private _seriesService: SerieService,
private _pageviewService: PageviewService,
private location: Location,
private _httpService: Http,
private seoService: SeoService
) {
this._router.events.subscribe((event) => {
if (event instanceof NavigationEnd){
//TODO: FIX TO RECOGNIZE PREVIOUS ROUTE -- THIS WILL CAUSE DUPLICATE REQUESTING URL
let slug = this._activatedRoute.snapshot.params['slug'];
this.slug = slug;
this.category = this._activatedRoute.snapshot.params['slug'];
this.getSeriesList(slug, null);
}
})
}
ngOnInit(){
let slug = this._activatedRoute.snapshot.params['slug'];
this.loading = true;
this.category = this._activatedRoute.snapshot.params['slug'];
this.getSeriesList(slug,"title");
this.service.setTitle(slug);
this.service.setMetaDescription(slug);
this.service.setMetaRobots('Index, Follow');
this._pageviewService.addPageview(
this.location.path(),"CATEGORY",slug,null)
.subscribe(res => {},err => {});
}
getSeriesList(slug, order_by) {
this._categoryService.getSeriesByCategory(slug, order_by)
.subscribe(
seriesList => this.seriesList = seriesList,
error => this.errorMessage = <any>error);
}
onReShuffle(order_by:string){
this.loading = true;
this._categoryService.getSeriesByCategory(
this._activatedRoute.snapshot.params['slug'], order_by)
.subscribe(
seriesList => {
this.seriesList = seriesList;
this.loading = false;
},
error => this.errorMessage = <any>error);
}
openPlaylistModal(series) {
// todo: open modal and pass series
console.log(series);
return
}
loadMore() {
this._httpService.get(this.seriesList.next_url)
.subscribe((res) => {
var results = res.json();
this.seriesList.result = t
this.seriesList.result.concat(results.result);
if(results.next_url){
this.seriesList.next_url = results.next_url;
}
else {
this.seriesList.next_url = false;
}
});
}
}
不知道我在做什么錯。 還有其他我不知道的方法嗎?
您不能注入Renderer2
,但是我們可以運行RendererFactory2
在@Injectable()
服務中獲取Renderer2
實例。 例如,Angular在Webworker中有內部使用的方法。
我用下面的代碼解決了這個問題:
import { Renderer2, RendererFactory2 } from '@angular/core';
@Injectable()
class Service {
private renderer: Renderer2;
constructor(rendererFactory: RendererFactory2) {
this.renderer = rendererFactory.createRenderer(null, null);
}
}
RendererFactory2.createRenderer
方法的參數為:
any
hostElement
type
,類型為RendererType2|null
您可以在此處看到(null, null)
參數: https : //github.com/angular/angular/blob/e3140ae888ac4037a5f119efaec7b1eaf8726286/packages/core/src/render/api.ts#L129
PS將Renderer2注入服務不是最好的主意。 任何渲染器操作都應包含在組件和指令中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.