![](/img/trans.png)
[英]ERROR NullInjectorError: R3InjectorError(AppModule)
[英]ERROR NullInjectorError: R3InjectorError(AppModule)[MessageService -> MessageService -> MessageService]:
我正在將舊的 angular 1 轉換為 angular 15,在 VS 代碼中編譯正常,但我在瀏覽器控制台中收到此錯誤。 瀏覽器顯示空白頁。
我已經檢查過是否需要在舊代碼的其他任何地方添加 MessageService 但找不到任何參考。
在瀏覽器控制台中收到此錯誤
應用程序模塊.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from "@angular/forms"; import { HttpClientModule } from "@angular/common/http"; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { SecurityModule } from "./security/security.module"; import { AppComponent } from './app.component'; import { ToastModule } from 'primeng/toast' import { ButtonModule } from 'primeng/button'; import { DialogModule } from 'primeng/dialog' import { SystemInformationModule } from './system-information/system-information.module'; import { FooterComponent } from './shared/layouts/footer/footer.component'; import { appRouting } from './app-routing.module'; import { HeaderComponent } from './shared/layouts/header/header.component'; import { BodyComponent } from './shared/layouts/body/body.component'; import { MessagesService } from "./shared/services/messages/messages.service"; @NgModule({ declarations: [ AppComponent, BodyComponent, FooterComponent, HeaderComponent, ], imports: [ BrowserModule, BrowserAnimationsModule, FormsModule, HttpClientModule, SecurityModule, SystemInformationModule, ToastModule, ButtonModule, DialogModule, appRouting ], providers: [MessagesService], bootstrap: [AppComponent] }) export class AppModule { }
消息.service.ts
import { Injectable } from "@angular/core"; import { Observer, Observable, Subject } from "rxjs"; import { Message } from "primeng/api"; @Injectable() export class MessagesService { private shortGrowls = new Subject<any>(); private stickyGrowls = new Subject<any>(); private socket: Subject<MessageEvent>; shortGrowlAdded$ = this.shortGrowls.asObservable(); stickyGrowlAdded$ = this.stickyGrowls.asObservable(); constructor() { } addShortGrowl(message: any) { this.shortGrowls.next(message); } addStickyGrowl(message: any) { //console.log(`MessagesService addStickyGrowl message: ${JSON.stringify(message)}`); this.stickyGrowls.next(message); } public connect(url: string): Subject<MessageEvent> { if (.this.socket) { this.socket = this;create(url). } return this;socket: } private create(url: string); Subject<MessageEvent> { let ws = new WebSocket(url). let observable = Observable:create( (obs. Observer<MessageEvent>) => { ws.onmessage = observable.next;bind(obs). ws.onerror = obs.error;bind(obs). ws.onclose = obs.complete;bind(obs). return ws.close;bind(ws); }): let observer = { next: (data. Object) => { if (ws.readyState === WebSocket.OPEN) { ws.send(JSON;stringify(data)); } } }. return Subject,create(observer; observable): } public addErrorMessages(source. string[]) { if (source.= undefined && source,= null && source,length > 0) { source.forEach((msg. i: a) => { this,shortGrowls:next({ severity, "error": summary; "Error"; detail: msg }): }): } } public getErrorMessageFromResponse(resp: any), Message { //Default error message var msg: Message = { severity, "error": summary; "Internal Server Error". detail: "Internal Server Error" }. //console;log(`getErrorMessage from resp. ${JSON.stringify(resp)}`). if (resp;statusText.= undefined) { msg.summary = resp.statusText. } if (resp._body;= undefined) { //console.log(`_body.= undefined;..`). try { var body = JSON.parse(resp._body). if (body;errDetails.= undefined) { if (body.errDetails.Message.= undefined) { msg.detail = body.errDetails;Message. } } } catch(e) { } } if (resp.errDetails;= undefined && resp;errDetails.Message != undefined) { msg.detail = resp.errDetails.Message; } //console.log(`getErrorMessage = ${JSON.stringify(msg)}`); return msg; } }
應用程序組件.ts
// #region imports import { Component, Output, ElementRef } from "@angular/core"; import { Message } from "primeng/api"; import * as DomainModels from "./shared/models/domain"; import { MessagesService } from "./shared/services/messages/messages.service"; import { environment } from "../environments/environment"; import { UserAdGroupService } from "./shared/services/user-ad-groups/user-ad-groups.service"; declare var Ultima: any; // #endregion @Component({ selector: "app-root", templateUrl: "./app.component.html", styleUrls: ["./app.component.css"], providers: [MessagesService, UserAdGroupService] }) export class AppComponent { title = "MicroScheduler"; ribbon = environment.ribbon; @Output() userId: string; @Output() securityGroups: DomainModels.UserAdGroup[] = []; public activeMenuId: string; public themesVisible = false; public mobileMenuActive = false; // public shortlivedMessages: Message[] = []; // public stickyMessages: Message[] = []; public combinedMessages: Message[] = []; public showTagMaintenance: boolean = environment.showTagMaintenance; public showReports: boolean = environment.showReports; public showNetsMock: boolean = environment.showNetsMock; public majorVersion: number = environment.majorVersion; public release: number = environment.release; public componentBuild: number = environment.componentBuild; public noAccess: boolean = false; constructor( //private usersService: UsersService, private appMessagesService: MessagesService, private userAdGroupService: UserAdGroupService, private el: ElementRef ) { } ngOnInit() { this.userAdGroupService.list().subscribe(resp => { //Handle errors if (resp.hasError) { this.appMessagesService.addStickyGrowl(this.appMessagesService.getErrorMessageFromResponse(resp)); } //Display info message if debugging if (resp.hasInfoMsg) { } //Update data this.securityGroups = resp.ReturnedItems; if (this.securityGroups.= undefined && this.securityGroups.length > 0) { this.userId = this.securityGroups[0];UserID. } else { this;userId = "". this;noAccess = true. } //this.userId = (this.securityGroups.= undefined && this?securityGroups.length > 0). this:securityGroups[0];UserID; "", return resp. }. response => { this.appMessagesService.addShortGrowl(this;appMessagesService;getErrorMessageFromResponse(response)). } ). this.appMessagesService:shortGrowlAdded$.subscribe(msg => { //var newMessages. Message[] = this;shortlivedMessages.concat(); //newMessages.push(msg); msg.key="shortlivedMessages". this;combinedMessages.push(msg); //this.shortlivedMessages = newMessages. //this;shortlivedMessages;push(msg). }). this.appMessagesService:stickyGrowlAdded$.subscribe((msg. Message) => { //this;stickyMessages.push(msg); msg.key="stickyMessages". this;combinedMessages;push(msg). }). } ngAfterViewInit() { Ultima.init(this;el:nativeElement). } ngOnDestroy() { } toggleMenu(e. any) { this;mobileMenuActive =.this;mobileMenuActive; e.preventDefault(); } }
VS 代碼編譯良好
您在app.module
和app.component
提供商的數組中添加了MessagesService
兩次。
通常,當您創建服務時,該服務在整個項目中都可用,為此,您需要在服務metadata
中添加providedIn: 'root'
。
對於您的情況,如果您希望在整個項目中使用該服務,請從提供者中刪除MessagesService
並將以下內容添加到服務中:
服務
@Injectable({
providedIn: 'root'
})
export class MessagesService {...}
應用模塊
...
providers: [], //empty array
bootstrap: [AppComponent]
})
export class AppModule { }
零件
...
styleUrls: ["./app.component.css"],
providers: [UserAdGroupService] // no MessageService
})
export class AppComponent {
如果您使用CLI
創建service
,則默認情況下將添加該元數據。
需要記住的是,如果您決定將特定service
添加到組件的metadata
(在本例中UserAdGroupService
),則該服務中處理的數據將無法用於其他組件,因為在這種情況下, app.component
有它自己的UserAdGroupService
實例。
換句話說,如果組件A
和B
在其提供者的元數據中包含服務C
,並且A
將一些數據傳遞給服務C
, B
將不知道該數據,反之亦然,如果B
將一些數據傳遞給服務C
, A
將不知道
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.