Angular里inject()在构造函数外为啥报错?

Designer°自阳 阅读 33

我在组件里想用inject()获取服务,但不在constructor里用,结果一运行就报错说“inject() must be called from an injection context”。

查了文档说Angular 14+支持在类方法或字段初始化时用inject(),但我这么写还是不行:

export class MyComponent {
  private userService = inject(UserService);

  ngOnInit() {
    this.userService.getUser();
  }
}

是不是我哪里配置错了?还是必须得用constructor注入?

我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
皇甫梓豪
这个问题挺有意思的,涉及到Angular依赖注入机制的一些细节。你提到的错误信息“inject() must be called from an injection context”确实有点让人困惑,特别是当你看到文档说从Angular 14开始支持在类字段初始化时使用inject()

根本原因是Angular的inject()函数依赖于一个上下文来确定当前的注入器(Injector)。这个上下文通常是通过构造函数中的@Injectable()装饰器或者是在构造函数中直接使用inject()来创建的。当你尝试在字段初始化阶段使用inject()时,Angular可能还没有完全设置好这个上下文。

尽管Angular 14及更高版本引入了对构造函数外使用inject()的支持,但在字段初始化阶段直接调用inject()仍然会遇到问题。这是因为字段初始化发生在构造函数执行之前,而Angular的依赖注入上下文是在构造函数中建立的。

解决这个问题的一个常见方法是在类的方法中使用inject(),而不是在字段初始化阶段。比如,你可以在ngOnInit生命周期钩子中使用inject(),因为此时Angular已经为组件设置了依赖注入上下文。

下面是修改后的代码示例:

import { Component, OnInit } from '@angular/core';
import { inject } from '@angular/core';
import { UserService } from './user.service';

@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
})
export class MyComponent implements OnInit {
private userService: UserService;

// 在ngOnInit中初始化userService
ngOnInit(): void {
this.userService = inject(UserService);
this.userService.getUser();
}
}


这样做的好处是确保了在调用inject()时,Angular的依赖注入上下文已经准备好。虽然看起来稍微绕了一点,但这是目前最可靠的方法之一。

另外,如果你想保持字段初始化的简洁性,可以考虑使用@Injectable()装饰器结合@Optional()@Self()等装饰器来实现,但这通常用于更复杂的依赖注入场景。

希望这能解决你的问题!如果还有其他疑惑,随时可以问我。
点赞
2026-03-21 12:10