子组件修改signal后父组件effect未触发问题排查求助
问题解决:子组件修改Model后父组件Effect不触发
问题出在这两点
- 子组件Model没和父组件Signal绑定:你子组件里
data = model({} as Vm)是自己新建了一个独立的Model,根本没和父组件的dataSignal关联上,改的是自己的局部数据,父组件的Signal当然没反应。 - 没遵守不可变更新规则:就算绑定对了,要是你只是修改对象内部属性(比如直接改
data().name),或者调用update(a => a)返回原对象,Signal是不会认的——Signal只认值的引用变了才触发更新,内部属性改了引用没变,Effect自然不会跑。
一步步修复
1. 子组件正确定义Model输入
子组件的Model要作为输入属性,和父组件的Signal关联:
import { model } from '@angular/core'; import { Vm } from './你的Vm类型路径'; export class ChildComponent { // 定义Model输入,指定类型 data = model<Vm>({}); onClick() { console.log("Click alters the data."); // 方法1:创建新对象触发更新(推荐,符合不可变要求) const current = this.data(); this.data.set({ ...current, // 这里写你要改的字段,比如: // username: '新名字', // list: [...current.list, { id: 5, content: '新条目' }] }); // 方法2:改数组里的对象时,也要创建新数组/对象 // this.data.update(prev => ({ // ...prev, // list: prev.list.map(item => // item.id === 2 ? {...item, content: '更新内容'} : item // ) // })); } }
2. 父组件模板加双向绑定
在父组件的模板里,把子组件的dataModel和父组件的dataSignal双向绑定:
<app-child [(data)]="data"></app-child>
这行代码是Angular Model的语法糖,相当于把子组件的Model和父组件的Signal连起来,子组件改Model时会同步更新父组件的Signal。
3. 必须创建新的引用才能触发更新
不管用set还是update,一定要返回新的对象/数组,不能直接改原对象的内部属性:
- ❌ 错误操作:
current.list[0].content = '改了'(直接改内部,引用没变) - ✅ 正确操作:
this.data.set({...current, list: [...current.list, 新条目]})(创建新对象/数组)
验证
改完之后,子组件点击时会生成新的对象引用,父组件的Signal能检测到变化,Effect就会触发了。轮询也能看到更新后的数据,每次修改都会触发Effect。
内容的提问来源于stack exchange,提问作者Konrad Viltersten
相关产品推荐
相关产品推荐

