无法从Angular服务中获取Signal值的问题求助
问题:Angular Service中Signal存储对象后获取为null
我尝试通过Service存储选中的Division对象,再在详情表单中获取该对象。设置操作时控制台能看到对象已填充,但获取时该对象却变为null。
相关代码
Division Service代码
private currentDivision = signal<Division>(new Division(), undefined); setCurrentDivision(division: Division): void { this.currentDivision.set(division); console.log(this.currentDivision()); } getCurrentDivision(): Division { console.log(this.currentDivision()); return this.currentDivision(); }
列表组件代码
onSelect(division: Division): void { this._divisionService.setCurrentDivision(division); }
详情表单组件代码
divisionService = inject(DivisionService); constructor(private fb: UntypedFormBuilder) { console.log(this.divisionService.getCurrentDivision()); this.division = this.divisionService.getCurrentDivision(); }
原因及解决方案
核心原因
- 初始化时机不匹配:详情表单组件的
constructor在组件创建时立即执行,大概率早于你在列表组件触发setCurrentDivision的时机——此时Service里的Signal还是初始的new Division(),如果你的Division默认构造生成的是空对象/null,就会出现获取到null的情况。 - 未利用Signal的响应式特性:在
constructor里仅获取一次Signal的值,不会追踪后续更新,就算之后Signal被修改,组件里的division变量也不会同步更新。
解决方法
1. 规范Signal初始化(可选)
Signal的第二个参数是配置项,无需传undefined,简化为:
private currentDivision = signal<Division>(new Division());
2. 响应式监听Signal变化
不要在constructor里一次性取值,改用computed或effect来追踪Signal的更新:
divisionService = inject(DivisionService); // 用computed创建响应式变量,模板中直接绑定即可 division = computed(() => this.divisionService.getCurrentDivision()); // 或者用effect监听变化,用于表单赋值等逻辑 constructor(private fb: UntypedFormBuilder) { effect(() => { const currentDiv = this.divisionService.getCurrentDivision(); console.log(currentDiv); this.fillForm(currentDiv); }); } private fillForm(division: Division) { // 将数据填充到表单 this.divisionForm.patchValue(division); }
3. 改用路由参数传递(更可靠的方案)
依赖Service存储对象容易受页面刷新、组件销毁重建影响,建议通过路由传递Division的ID,在详情组件中重新获取数据:
// 列表组件跳转时携带ID onSelect(division: Division): void { this.router.navigate(['/division/detail', division.id]); } // 详情组件通过路由ID获取数据 constructor( private fb: UntypedFormBuilder, private route: ActivatedRoute, private divisionService: DivisionService ) { const divId = this.route.snapshot.paramMap.get('id'); if (divId) { this.divisionService.getDivisionById(divId).subscribe(division => { this.division = division; this.fillForm(division); }); } }
内容的提问来源于stack exchange,提问作者Rich
相关产品推荐
相关产品推荐

