![](/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.