Angular 14升级至20后,成员变量注入的服务在ngOnInit中为undefined的问题咨询
Angular 14升级至20后,成员变量注入的服务在ngOnInit中为undefined的问题咨询
你好呀,我来帮你排查下这个问题~ 你遇到的服务在ngOnInit里变成undefined的情况,大概率是因为用错了Angular的注入语法,下面给你拆解原因和正确的写法:
问题根源:混淆了Inject装饰器与inject()注入函数
你目前的写法里有两个关键问题:
- 如果你想用类成员变量直接注入,应该用小写的
inject()函数(Angular 14+新增的注入方式),而不是大写的Inject装饰器直接赋值。大写的Inject是用来标记构造函数参数或类成员的装饰器,单独拿出来赋值不会触发Angular的注入逻辑,自然会得到undefined。 - 就算用
@Inject()装饰器标记成员变量,也要确保服务的提供者配置正确,否则Angular找不到对应的服务实例。
两种正确的写法推荐
写法一:使用inject()函数(更简洁,Angular官方推荐)
首先要导入小写的inject函数,然后直接在成员变量初始化时调用它:
import { inject, Component, OnInit, Input } from '@angular/core'; import { CodeOfficielGographiqueService, Commune } from '../../../../openapi'; import { environment } from '../../../environments/environment'; import { CommuneService} from '../../core/services/commune.service'; /** Combobox en autocomplete des communes du COG */ @Component({ selector: 'app-communes', templateUrl: './communes.component.html', styleUrls: ['./communes.component.scss'], standalone: false }) export class CommunesComponent implements OnInit { /** Année du Code Officiel Géographique. */ @Input() anneeCOG: number; /** Locale du tri des communes */ @Input() locale: string = 'fr_FR'; /** Liste des communes ordonnées par locale */ communes: Commune[] = [] as Array<Commune>; /** Codes communes avec leur commune associée. */ communesMap: Map<string, Commune> = new Map<string, Commune>(); /** Code commune sélectionné. */ codeCommune: string = null; /** Commune sélectionnée (objet). */ communeSelectionnee: Commune = null; /** Libellé final de la commune sélectionnée. */ libelleCommuneSelectionnee: string; /** Gestion des communes (REST) */ private readonly communeService: CommuneService = inject(CommuneService); /** Code Officiel Géographique (REST) */ private readonly cogService: CodeOfficielGographiqueService = inject(CodeOfficielGographiqueService); constructor() { } ngOnInit(): void { this.cogService.configuration.basePath = environment.spark_url; // ...你的其他初始化逻辑 } }
写法二:使用@Inject()装饰器标记成员变量
这种方式需要在成员变量上添加@Inject()装饰器,确保Angular能识别要注入的服务:
import { Inject, Component, OnInit, Input } from '@angular/core'; import { CodeOfficielGographiqueService, Commune } from '../../../../openapi'; import { environment } from '../../../environments/environment'; import { CommuneService} from '../../core/services/commune.service'; /** Combobox en autocomplete des communes du COG */ @Component({ selector: 'app-communes', templateUrl: './communes.component.html', styleUrls: ['./communes.component.scss'], standalone: false }) export class CommunesComponent implements OnInit { /** Année du Code Officiel Géographique. */ @Input() anneeCOG: number; /** Locale du tri des communes */ @Input() locale: string = 'fr_FR'; /** Liste des communes ordonnées par locale */ communes: Commune[] = [] as Array<Commune>; /** Codes communes avec leur commune associée. */ communesMap: Map<string, Commune> = new Map<string, Commune>(); /** Code commune sélectionné. */ codeCommune: string = null; /** Commune sélectionnée (objet). */ communeSelectionnee: Commune = null; /** Libellé final de la commune sélectionnée. */ libelleCommuneSelectionnee: string; /** Gestion des communes (REST) */ @Inject(CommuneService) private readonly communeService: CommuneService; /** Code Officiel Géographique (REST) */ @Inject(CodeOfficielGographiqueService) private readonly cogService: CodeOfficielGographiqueService; constructor() { } ngOnInit(): void { this.cogService.configuration.basePath = environment.spark_url; // ...你的其他初始化逻辑 } }
额外检查点
- 确认服务的提供者配置:检查你的
CommuneService和CodeOfficielGographiqueService类上是否有@Injectable({ providedIn: 'root' })装饰器,如果没有,需要在组件所在的NgModule的providers数组中添加这两个服务。 - 确保注入上下文正确:
inject()函数只能在Angular的注入上下文内调用,组件的成员变量初始化是符合要求的,只要组件是由Angular实例化的(不要手动new CommunesComponent())。
这样修改后,你的服务应该就能在ngOnInit中正常访问啦~
内容来源于stack exchange
相关产品推荐
相关产品推荐

