我目前正在重构我的一项升级服务。我不得不替换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;
}
});
}
}
不确定我做错了什么。有没有其他方法可以做到这一点,我不知道?
答案 0 :(得分:2)
您无法注入Renderer2
,但我们可以运行RendererFactory2
来获取Renderer2
服务中的@Injectable()
实例。
例如,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
P.S。将Renderer2注入服务并不是最好的主意。任何渲染器操作都应该放在组件和指令中。