![](/img/trans.png)
[英]How could I add or "inject" a component from a service to the dom in angular?
[英]How can I inject a parameter from a component to a service in Angular?
你好,
在我遵循《英雄之旅》指南時,我想嘗試一下具有多個數據數組選項以及我使用哪些 herosUrl 從 InMemoryDbService 請求數據。 我希望能夠將 heros 組件中的 herosUrl 參數傳遞給 heros 服務,以確定我想從數據庫中獲取哪一批英雄,但我在控制台中收到以下錯誤消息:
vendor.js:14812 ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(AppModule)[HeroService -> heroesUrl -> heroesUrl -> heroesUrl]:
NullInjectorError: No provider for heroesUrl!
NullInjectorError: R3InjectorError(AppModule)[HeroService -> heroesUrl -> heroesUrl -> heroesUrl]:
NullInjectorError: No provider for heroesUrl!
at NullInjector.get (vendor.js:10919)
at R3Injector.get (vendor.js:24642)
at R3Injector.get (vendor.js:24642)
at R3Injector.get (vendor.js:24642)
at injectInjectorOnly (vendor.js:10774)
at Module.ɵɵinject (vendor.js:10784)
at Object.HeroService_Factory [as factory] (main.js:503)
at R3Injector.hydrate (vendor.js:24869)
at R3Injector.get (vendor.js:24630)
at NgModuleRef$1.get (vendor.js:41631)
at resolvePromise (polyfills.js:806)
at resolvePromise (polyfills.js:765)
at polyfills.js:867
at ZoneDelegate.invokeTask (polyfills.js:413)
at Object.onInvokeTask (vendor.js:46107)
at ZoneDelegate.invokeTask (polyfills.js:412)
at Zone.runTask (polyfills.js:181)
at drainMicroTaskQueue (polyfills.js:583)
它說heresUrl沒有提供者,所以我懷疑我沒有以正確的方式在組件中定義提供者:
import { Component, OnInit } from "@angular/core";
import { Hero } from "../hero";
import { HeroService } from "../hero.service";
import { MessageService } from "../message.service";
@Component({
selector: "app-heroes",
templateUrl: "./heroes.component.html",
styleUrls: ["./heroes.component.scss"],
providers: [{ provide: "heroesUrl", useValue: "heroesTwo" }] //<-------------
})
export class HeroesComponent implements OnInit {
heroes: Hero[];
constructor(
private heroService: HeroService,
public messageService: MessageService
) {}
ngOnInit(): void {
this.heroService.getHeroes().subscribe(heroes => (this.heroes = heroes));
}
}
這是服務的樣子,我試圖在其中注入參數:
import { Observable, of } from "rxjs";
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Injectable, Input, Inject, Optional } from "@angular/core";
import { Hero } from "./hero";
import { MessageService } from "./message.service";
import { catchError, map, tap } from "rxjs/operators";
@Injectable({
providedIn: "root"
})
export class HeroService {
constructor(
private http: HttpClient,
private messageService: MessageService,
@Inject("heroesUrl") private heroesUrl: string //<-------------
) {}
getHeroes(): Observable<Hero[]> {
return this.http.get<Hero[]>(this.heroesUrl).pipe(
tap(tappedData =>
this.log("Fetched heroes: " + tappedData.map(data => data.name))
),
catchError(this.handleError<Hero[]>("getHeroes", []))
);
}
getHero(id: number): Observable<Hero> {
const url = this.heroesUrl + "/" + id;
return this.http.get<Hero>(url).pipe(
tap(_ => this.log("fetched hero id=" + id)),
catchError(this.handleError<Hero>("getHero id=" + id))
);
}
private log(message: string) {
this.messageService.add(`HeroService: ${message}`);
}
private handleError<T>(operation = "operation", result?: T) {
return (error: any): Observable<T> => {
console.error(error);
this.log(`${operation} failed: ${error.body.error}`);
return of(result as T);
};
}
}
在攔截http調用的服務中,實現InMemoryDbService:
return { heroesOne: heroes1, heroesTwo: heroes2 };
我一直在特別關注這些指南:
https://www.inversionofcontrol.co.uk/injection-tokens-in-angular/
https://dev.to/leonelngande/passing-additional-parameters-to-an-angular-service-pma
有人可以解釋一下我做錯了什么嗎?
添加這一行 -> providers: [{ provide: "heroesUrl", useValue: "heroesTwo" }] 到 Module.ts 文件提供者數組而不是組件 ts 文件並嘗試。
您需要在 app.module.ts 的提供者中聲明您的 herosUrl,但是每個 hero 服務都會提供相同的 url。
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [
HeroService,
{ provide: "heroesUrl", useValue: "heroesOne" }
],
bootstrap: [AppComponent]
})
或者您也使用服務和 url 在組件中聲明您的提供者,然后每個組件將擁有自己的服務和自己的 url。
@Component({
selector: "app-heroes",
templateUrl: "./heroes.component.html",
styleUrls: ["./heroes.component.scss"],
providers: [
HeroService,
{ provide: "heroesUrl", useValue: "heroesTwo" }
]
})
並且您可以將兩者結合起來使用帶有“heroesOne”網址的通用 HeroesService 以及針對特定組件的其他 HeroesService 和其他網址。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.