说我在路线#/user/1
上,并将路线更改为#/user/2
。它不会触发预期的ngOnInit
,因为它是已经初始化的相同组件。
在当前设置中,resolver
路由上的user/{id}
获取用户数据,然后组件上可以使用属性this.user$
,然后我们可以订阅该属性,或者接收平原来自@Input
的对象; this.user
。
然后在ngOnInit
中我们创建了一个formBuilder:
@Input() user: User;
ngOnInit () {
this.userFormGroup = this.formBuilder.group({
firstName: [ this.user.firstName ],
lastName: [ this.user.lastName ]
});
}
当我更改路线中的id
时会发生什么,表格未更新。
解决方案是让组件以某种方式重新渲染(在React中你可以通过将唯一的key
属性传递给组件来强制它,强制它重新渲染),但我不知道我知道如何,特别是如果路由器直接调用该组件。
目前我们有解决方法:
user$: Observable<User>;
user: User;
ngOnInit () {
this.user$.subscribe((user: User) => {
this.user = user;
this.initUserForm();
});
}
initUserForm () {
this.userFormGroup = this.formBuilder.group({
firstName: [ this.user.firstName ],
lastName: [ this.user.lastName ]
});
}
其中介绍了一些新问题:
如果user$
Observable被应用程序的其他部分触发,它将覆盖当前的表单值。
我必须确保user$
对象上的任何更改都是最新的,我不想在每次按键或更改时更新它。
我希望反应形式具有反应性,因为它会在状态发生变化时更新表单,不知何故单向绑定到状态。
其他解决方法(没有订阅)将是:
@Input() user: User;
ngOnChanges (changes: SimpleChanges) {
if (changes.user && changes.user.previousValue) {
if (changes.user.currentValue.id !== changes.user.previousValue.id){
this.initUserForm();
}
}
}
initUserForm () {
this.userFormGroup = this.formBuilder.group({
firstName: [ this.user.firstName ],
lastName: [ this.user.lastName ]
});
}
哪个比第一个更麻烦,但是不需要刷新的问题就少了。
但是有些东西告诉我必须有更好的方法来实现表单,并在id
之间切换。
如果以某种方式我们可以触发组件重新渲染以解决它,或者以更整齐的方式在组件上解决它并使反应形式真正被反应。
作为旁注,我们使用ng4和ngrx4,但我们不希望在提交之后将所有表单状态更改都放在商店中。