Angular NullInjectorError求助:无Flashcard提供者
Angular CRUD闪卡应用NullInjectorError问题解决
错误信息
flashcards-area.component.ts:24 ERROR NullInjectorError: R3InjectorError(AppModule)[Flashcard -> Flashcard -> Flashcard]: NullInjectorError: No provider for Flashcard! at NullInjector.get (core.mjs:6368:27) at R3Injector.get (core.mjs:6795:33) at R3Injector.get (core.mjs:6795:33) at R3Injector.get (core.mjs:6795:33) at ChainedInjector.get (core.mjs:13866:36) at lookupTokenUsingModuleInjector (core.mjs:3290:39) at getOrCreateInjectable (core.mjs:3335:12) at Module.ɵɵdirectiveInject (core.mjs:10881:12) at NodeInjectorFactory.FlashcardComponent_Factory [as factory] (flashcard.component.ts:11:32) at getNodeInjectable (core.mjs:3520:44)
相关代码
Flashcard类
export class Flashcard { public id?: any; public question:string; public answer: string; public learned: boolean = false; public chapter?: number; public displayed?: boolean = true; constructor(question: string, answer: string, chapter?: number, learned?: boolean, id?: any, displayed?: boolean){ this.question = question; this.answer = answer; this.chapter = chapter; this.id = id; } } export default Flashcard;
FullFlashcardsListService服务
import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http'; import { Observable, of, throwError } from 'rxjs'; import { catchError, retry } from 'rxjs/operators'; import { Flashcard } from '../classes/flashcard'; import { map } from 'rxjs/operators'; import { Subject } from 'rxjs'; const httpOptions = { headers: new HttpHeaders({'Content-Type': 'application/json'}) }; @Injectable({ providedIn: 'root' }) export class FullFlashcardsListService { private baseURL: string = "/api/v1/flashcards"; constructor(private http: HttpClient) { } getAll() { return this.http.get<Flashcard[]>(this.baseURL); } }; export default FullFlashcardsListService;
FlashcardsAreaComponent父组件
import { Component, OnInit } from '@angular/core'; import { Flashcard } from '../classes/flashcard' import { FullFlashcardsListService } from '../services/full-flashcards-list.service'; @Component({ selector: 'app-flashcards-area', templateUrl: './flashcards-area.component.html', styleUrls: ['./flashcards-area.component.css'], }) export class FlashcardsAreaComponent implements OnInit { fullFlashcards?: Flashcard[] = []; constructor( private fullFlashcardsListService: FullFlashcardsListService, ) {} ngOnInit(): void { this.retrieveFlashcards(); } retrieveFlashcards() { this.fullFlashcardsListService.getAll() .subscribe(response => { console.log(response); this.fullFlashcards = response }) }
FlashcardsArea模板HTML
<div class="flashcards-container"> <app-flashcard *ngFor="let card of fullFlashcards; let i = index" [flashcard]="card" (deleteCard)="deleteConfirmation(i)" (refreshFlashcards)="retrieveFlashcards()"></app-flashcard> </div>
FlashcardComponent子组件
import { Component, EventEmitter, Inject, Input, OnInit, Output } from '@angular/core'; import { Flashcard } from '../classes/flashcard'; import FullFlashcardsListService from '../services/full-flashcards-list.service'; @Component({ selector: 'app-flashcard', templateUrl: './flashcard.component.html', styleUrls: ['./flashcard.component.css'] }) export class FlashcardComponent implements OnInit { @Input() flashcard!: Flashcard; showAnswer: boolean = false; displayed: boolean = true; delete: boolean = false; @Output() dontDisplay = new EventEmitter(); @Output() deleteCard = new EventEmitter(); constructor(flashcard: Flashcard) { this.flashcard = flashcard; } ngOnInit(): void { } revealAnswer() { this.showAnswer = !this.showAnswer; } hideCard() { this.dontDisplay.emit(); } removeCard() { this.deleteCard.emit(); } }
Flashcard模板HTML
<div class="flashcard-container" *ngIf="flashcard.displayed"> <mat-card class="flashcard"> <mat-card-title-group class="mat-card-title"> <mat-card-title class="title">Chapter {{flashcard.chapter}}</mat-card-title> <button mat-button class="check" (click)="hideCard()"> <mat-icon class="icon" >check</mat-icon> </button> <button mat-button class="trash" (click)="removeCard()"> <mat-icon class="icon">delete</mat-icon> </button> </mat-card-title-group> <mat-divider class="material-divider"></mat-divider> <div class="answer_container" (click)="revealAnswer()"> <mat-card-content class="flashcard_question"> {{flashcard.question}} </mat-card-content> <mat-card-content *ngIf="showAnswer" class="flashcard_answer"> {{flashcard.answer}} </mat-card-content> </div> </mat-card> </div> export default FlashcardComponent;
AppModule
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { MatToolbarModule } from '@angular/material/toolbar'; import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatCardModule } from '@angular/material/card'; import { MatInputModule } from '@angular/material/input'; import { MatDividerModule } from '@angular/material/divider'; import { FormsModule } from '@angular/forms'; import {MatSidenavModule} from '@angular/material/sidenav'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { NavbarComponent } from './navbar/navbar.component'; import { EntryCardComponent } from './entry-card/entry-card.component'; import { TitleHeadingComponent } from './title-heading/title-heading.component'; import { FlashcardComponent } from './flashcard/flashcard.component'; import { FlashcardsAreaComponent } from './flashcards-area/flashcards-area.component'; import { ResetButtonComponent } from './reset-button/reset-button.component'; import { FlashcardsListService } from './services/flashcards-list.service'; import { HttpClientModule } from '@angular/common/http'; import { TrashButtonComponent } from './trash-button/trash-button.component'; import { FullFlashcardsListService } from './services/full-flashcards-list.service'; import { CurrentDisplayedFlashcardsService } from './services/current-displayed-flashcards.service'; @NgModule({ declarations: [ AppComponent, NavbarComponent, EntryCardComponent, TitleHeadingComponent, FlashcardComponent, FlashcardsAreaComponent, ResetButtonComponent, TrashButtonComponent, ], imports: [ BrowserModule, AppRoutingModule, BrowserAnimationsModule, MatToolbarModule, MatButtonModule, MatIconModule, MatMenuModule, MatCardModule, MatInputModule, MatDividerModule, FormsModule, MatSidenavModule, HttpClientModule, ], providers: [ FlashcardsListService, FullFlashcardsListService, CurrentDisplayedFlashcardsService ], bootstrap: [AppComponent] }) export class AppModule { }
问题原因及解决方案
问题出在FlashcardComponent的构造函数中,你试图注入Flashcard类——但Flashcard只是普通数据模型类,并非Angular可注入服务,Angular无法为其提供依赖实例,因此抛出错误。
修改步骤
删除FlashcardComponent构造函数中对Flashcard的注入,因为已经通过@Input()装饰器接收父组件传递的flashcard数据,无需构造函数注入。
修改后的FlashcardComponent构造函数:
constructor() { }
保留@Input() flashcard!: Flashcard;,父组件通过[flashcard]="card"传递数据的逻辑是正确的,无需修改。
内容的提问来源于stack exchange,提问作者Justin
相关产品推荐
相关产品推荐

