我已经看过,阅读并尝试过许多有关此主题的问题,答案和博客。我了解为什么我的代码中会发生这种情况,只是不知道如何解决。
(简化真实代码;如果我犯了错误或忘记了重要的事情,请在评论中让我知道)
我有一个带有输入的上级组件A和一个下级组件B。
<form [formgroup]="modalForm">
<input type="text" formControlName="text"></input>
<componentB
[formControl]="modalForm.controls['componentB']
[firstProperty]="foo"
[secondProperty]="bar">
</componentB>
</form>
ComponentB也有一个输入和一个自定义消息组件:
<div>
<input type="text" [formControl]="formControl"></input>
<message
[message]="firstProperty"
[secondMessage]="secondProperty">
</message>
</div>
ComponentA:
export class ComponentA implements OnInit{
public foo: string;
public bar: string;
public modalFrom: FormGroup;
public constructor(private componentBValidatorFactory: ComponentBValidatorFactory){}
public ngOnInit(): void {
this.modalForm = new FormGroup({
text: new FormControl(null),
componentB: new FormControl(null, {
validators: Validators.required,
asyncValidatiors: [this.componentBValidatorFactory.asyncValidatorFn()],
updateOn: 'blur'
})
});
this.modalForm.controls['text'].valueChanges(subscribe( () => this.textChanged());
this.modalForm.controls['componentB'].valueChanges(subscribe( () => this.componentBChanged());
}
private textChanged(): void {
this.foo = this.modalForm.controls['text'].value;
}
private componentBChanged(): void {
this.bar = this.modalForm.controls['componentB'].value + 'somestring';
}
}
ComponentB(简体):
export class ComponentB{
@Input()
public formControl: FormControl;
@Input()
public firstProperty: string;
@Input()
public secondProperty: string;
}
问题(据我了解):
text
发生更改(用户输入)时,它将使用值更新foo
。这意味着ComponentB
发生了变化,因此ComponentB的valueChanges
被触发。 ComponentBChanged
被触发并更新bar
。
当text
再次更改时,bar
再次更改,但是由于它与第二次处理foo
时的先前值不同,我得到了众所周知的ExpressionChangedAfterItHasBeenCheckedError
(值已正确处理)。
据我了解:
ComponentB
已更新(foo
),这将触发同一组件(bar
)绑定的另一项更改。这并不能使Angular开心。
直接将输入放入ComponentB
(也有一个输入字段)可以很好地工作,它可以正确更新bar
,而不会出现问题。
我该怎么做才能无问题地更新bar
?我无法在代码中的bar
中更新textChanged
,因为如果直接操纵ComponentB
,更新也应该发生。
答案 0 :(得分:0)
不是将FormControl传递给child Use,而是将foo和bar属性分配为null
formControlDirective
此伪指令接受现有的FormGroup实例。然后它将 使用此FormGroup实例来匹配任何子FormControl,FormGroup, 和FormArray实例添加到子FormControlName,FormGroupName和 FormArrayName指令。
Parent.component.html
@RequestMapping(path = "/handleResponse", method = RequestMethod.GET)
public String handleResponse(@RequestParam(name = "token")
final String token, @RequestParam(name = "PayerID")
final String payerId)
app-component-a.ts
<form [formGroup]="form">
<label >Text</label>
<input formControlName="text">
<app-component-a
[firstProperty]="foo"
[secondProperty]="bar"
></app-component-a>
</form>