簡體   English   中英

錯誤:Renderer2沒有提供程序! Angular v 4.1.3

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM