(字幕:我认为我的代码闹鬼......)
我有一个包含2个孩子的父组件:Notes和Location。位置正在发送更改,并由父级接收。这工作正常。注释正在发出,但显然它从未被父母接收过。
位置输入属性:
@Input() public FactLocation :LocationInfo ; //object initialized later
Notes输入属性:
@Input() public FactNotes : string = "start";
位置HTML:
<location-field [(FieldLocation)]="FactLocation" ></location-field>
备注HTML:
<notes-field [(FieldNotes)]="FactNotes"></notes-field>
位置组件输入/输出:
@Input() FieldLocation: LocationInfo;
@Output() locationEmitter: EventEmitter<LocationInfo> = new EventEmitter<LocationInfo>();
Notes组件输入/输出:
@Input() FieldNotes :string;
@Output() notesEmitter: EventEmitter<string> = new EventEmitter<string>();
位置发射器声明:
this.locationEmitter.emit(this.FieldLocation);
注释发射器调用:
this.notesEmitter.emit(this.FieldNotes);
当我在Location子组件中更改FieldLocation属性的值时,该值将反映在父组件中。当我更改Notes子组件中FieldNotes属性的值时,它将在本地更改,但在父组件中永远不会更改。
以下是从子组件发出事件时应调用的方法:
public FactLocationChange(evt :LocationInfo){
console.log(evt);
this.FactLocation = evt;
}
public FactNotesChange(evt :string){
console.log(evt);
this.FactNotes = evt;
}
尽管我可以说,这两者之间的一切都是相同的,除了属性名称以及位置发射器响应子节点中的KeyDown事件而发出信号,并且Notes发射器位于计时器上(间隔)。
我错过了什么?
谢谢, 戴夫
PS:这是代码的“闹鬼”部分......上面发布的两个“更改”方法在发出事件时应该被调用注释,但位置仍然有效。我在调试时注意到这一点 - 在FactLocationChange方法中放置一个“调试器”语句没有任何区别,即使父进程中的位置正在更新。调试器从未踢过。我尝试过评论,取消注释,重新启动,删除所有JS文件的方法,并让TSC重新生成它们,所有这些都没有任何变化。我很困惑。
答案 0 :(得分:1)
你的代码没有闹鬼;)
实际上,即使你认为另一个正在发光,但实际上并非如此。
对象是可变的,因此父对象将为对象FactLocation
“自动”获取值。这就是为什么父母得到更新,即使你已经评论了发射,就像你在问题的最后提到的那样。传递这样的对象时,实际上是在父对象中传递对象的引用,这就是更改影响父对象的原因。
原始类型,比如你的字符串是不可变的,因此它不像你的对象一样发出父变化。
您正在将双向绑定与“常规”Output
单向绑定混合,因此它不会发出。如果你想要双向绑定,就像你想要的那样,你需要在你的发射器中添加后缀Change
,它也需要与输入具有相同的前缀(名称)。所以它应该是:
@Output() FieldNotesChange: EventEmitter<string> = new EventEmitter<string>();
然后发出:
public FactNotesChange(evt :string){
this.FiedNotesChange.emit(evt)
}