[解決済み] Angular InjectionTokenが「No provider for InjectionToken」をスローします。
2022-02-19 23:56:57
質問
現在、新しいAngularフレームワークを学んでいますが、バックエンドサービスに問い合わせるためのサービスを動的に解決するために、サービス名を引数として受け取る動的検索バーを作ろうとしています。
このために、私は
Injector
の間にサービスをロードします。
ngOnInit
. これは文字列ベースのプロバイダを使用しているときはうまくいきますが、私の IDE では、これは非推奨であり
InjectionToken
というのは、どうも腑に落ちない。
のインスタンスをすべて削除することで、以下のコードが機能することを期待しました。
InjectionToken
という文字列リテラルに直接置き換えることで動作します。
以下のドキュメントを見てみましたが、書いてある通りにやったのに、うまくいかないと言われ続けている気がして、よく理解できませんでした。 https://angular.io/guide/dependency-injection-providers
何が間違っているのか、誰か教えてください。
ありがとうございます
モジュール宣言
// app.module.ts
@NgModule({
declarations: [
AppComponent,
SearchBarComponent
],
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule
],
providers: [
{
provide: new InjectionToken<ISearchable>('CustomerService'), // <-- doesn't work; 'CustomerService' <-- works
useValue: CustomerService
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
検索バーコンポーネントです。
// search-bar.component.ts
@Component({
selector: 'search-bar',
templateUrl: './search-bar.component.html',
styleUrls: ['./search-bar.component.sass']
})
export class SearchBarComponent implements OnInit {
@Input()
source: string;
private searcher: ISearchable;
constructor(private injector: Injector) {}
ngOnInit() {
// error: Error: No provider for InjectionToken CustomerService!
let token = new InjectionToken<ISearchable>(this.source);
this.searcher = this.injector.get<ISearchable>(token);
// this works, but it's deprecated and will probably break in the future
// this.searcher = this.injector.get(this.source);
console.log(this.searcher);
}
}
検索バーを使う
<!-- app.component.html -->
<div class="row justify-content-center mb-2">
<div class="col-8">
<search-bar title="Customers" source="CustomerService"></search-bar>
</div>
</div>
Edit: エラーが発生した例です。
https://stackblitz.com/edit/angular-3admbe
解決方法は?
angularの公式リポジトリで聞いてみたところ、簡単な解決策であることが判明しました。サービス名を文字列で渡す代わりに、トークンをコンポーネントからビューに通して、別のコンポーネントに渡す必要があります。
インジェクショントークンをグローバルに定義する
私はこれを自分のサービス自体と並行して行い、追跡を容易にしました。
@Injectable()
export class CustomerService implements ISearchable { ... }
export const CUSTOMER_SERVICE = new InjectionToken<ISearchable>('CustomerService');
インジェクショントークンをアプリプロバイダに登録する
import {CUSTOMER_SERVICE, CustomerService} from "./services/customer/customer.service";
@NgModule({
declarations: [ ... ],
imports: [ ... ],
providers: [
{
provide: CUSTOMER_SERVICE, // That's the token we defined previously
useClass: CustomerService, // That's the actual service itself
}
],
bootstrap: [ ... ],
})
export class AppModule { }
トークンをビューから他のコンポーネントに渡します。
// In your component
import {CUSTOMER_SERVICE} from "./services/customer/customer.service";
@Component({
selector: 'app-root',
template: '<app-search-bar [source]="searcher"></app-search-bar>'
})
export class AppComponent
{
searcher = CUSTOMER_SERVICE;
}
他のコンポーネントから動的にサービスをインポートできるようになりました。
@Component({
selector: 'app-search-bar',
templateUrl: './search-bar.component.html',
styleUrls: ['./search-bar.component.sass'],
})
export class SearchBarComponent implements OnInit
{
@Input()
source: InjectionToken<ISearchable>;
private searcher: ISearchable;
constructor(private injector: Injector) {}
ngOnInit()
{
this.searcher = this.injector.get<ISearchable>(this.source);
}
search(query: string)
{
this.searcher.search(query).subscribe(...);
}
}
関連
-
[解決済み】アンギュラーコンポーネントにサービスを注入しようとするとエラー "EXCEPTION: Can't resolve all parameters for component"、なぜ?
-
[解決済み】angularでpreflightのレスポンスがHTTP okステータスにならない。
-
[解決済み] Angular EXCEPTION: Http用のプロバイダがありません。
-
[解決済み] NgModule が見つかりませんでした。NgModule でのインポートをスキップするには skip-import オプションを使用します。
-
[解決済み] ReferenceError: localStorageが定義されていません。
-
[解決済み] AngularのngClassとトグルクラスのクリックイベント
-
[解決済み] "エラーです。オーバーレイのプロバイダがありません!"
-
[解決済み] Angular 6でmouseoverとmouseoutを使用する方法
-
[解決済み] Angular HTMLバインディング
-
[解決済み] AngularでNameServiceのプロバイダがない
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Angular2エラー。exportAs "が "ngForm "に設定されたディレクティブは存在しません。
-
[解決済み] Angular material Angular Material コアテーマが見つかりませんでした。
-
[解決済み] Angular 2で簡単なアコーディオンを作成するにはどうすればよいですか?
-
[解決済み] NullInjectorError: MatDialogRef 用のプロバイダがありません
-
[解決済み] Angular CLIでピア依存をインストールする場合の対処方法は?
-
[解決済み] Electron - ローカルリソースのロードが許可されていません
-
[解決済み] ActivatedRouteSnapshot の注入ができない。
-
[解決済み] Angular 2でディレイを作成する方法
-
[解決済み] エラーです。参照または変数に代入できません! Angular 4 [重複]の場合
-
[解決済み] ブレークポイントの解除 - VS Code | Chrome | Angular