使用@for指令的Angular视图未随Signal更新,求排查方案
问题原因及解决办法
你的问题在于workers是普通类属性,Angular的变更检测机制无法自动感知到它的更新——尽管你在effect里给它赋了新值,但这种普通赋值不会触发UI重新渲染。
解决方案1:使用Angular信号(推荐,Angular 16+)
将workers改为响应式信号,信号值的变化会自动触发UI更新:
@Component({ selector: 'app-planning-workers', templateUrl: './workers.component.html', styleUrl: './workers.component.scss', }) export class WorkersComponent { private planningStore = inject(PlanningStore); // 定义为响应式信号 workers = signal<Worker[]>([]); constructor() { effect(() => { // 使用set方法更新信号值 this.workers.set(this.planningStore.workers()); }); } }
模板中需要调用信号获取最新值:
<div class='people-wrapper'> <div class='people-bubble-wrapper'> @for (worker of workers(); track worker.id) { <app-bubble [worker]='worker'></app-bubble> } </div> </div>
解决方案2:使用Observable + Async管道
如果更习惯RxJS的方式,可以将Store的信号转为Observable,配合async管道自动处理订阅与更新:
import { toObservable } from '@angular/core/rxjs-interop'; import { Observable } from 'rxjs'; @Component({ selector: 'app-planning-workers', templateUrl: './workers.component.html', styleUrl: './workers.component.scss', }) export class WorkersComponent { private planningStore = inject(PlanningStore); // 将信号转为Observable workers$: Observable<Worker[]> = toObservable(this.planningStore.workers); }
模板中使用async管道订阅并渲染:
<div class='people-wrapper'> <div class='people-bubble-wrapper'> @for (worker of workers$ | async; track worker.id) { <app-bubble [worker]='worker'></app-bubble> } </div> </div>
原写法失效的核心原因
Angular的变更检测默认只追踪输入属性、事件绑定等响应式触发点,普通类属性的赋值不在其自动检测范围内。而信号是Angular原生支持的响应式数据源,值变更时会主动通知依赖的模板更新;Async管道则会自动订阅Observable,并在值变化时触发UI重新渲染。
内容的提问来源于stack exchange,提问作者Damian Kapłon
相关产品推荐
相关产品推荐

