我正在开发一个移动的应用程序,使用离子和Angular 以及React形式。
我有一个可重用的组件来输入电话号码,这个组件实现了ControlValueAccessor
接口。另外,这个组件下面有一个按钮,用来从联系人列表中选择电话号码,当我以编程方式设置这个值时,onChange事件被触发两次。
可重复使用的组件
export class PhoneNumberFormControl implements ControlValueAccessor {
value: string;
/**
* With this I change the value programmatically.
*/
set newValue(newValue: T) {
if (newValue !== this.value) {
this.value = newValue;
this.onChange(newValue); // <= Notify the parent form
}
}
onChange = (newValue: T) => {};
onTouched = () => {};
constructor(
@Optional() @Self() public ngControl: NgControl
) {
if (ngControl != null) {
ngControl.valueAccessor = this;
}
}
writeValue(value: T): void {
if (value !== this.value) {
this.value = value;
}
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
}
async openModal() {
// Logic to open a modal
string phoneNumber = '7871234567';
if (phoneNumber) {
// 1. Changing the value programmatically, onChange is called, see setter above
this.newValue = phoneNumber;
// 2. Let the parent know that the input was touched because you have used the modal. This is wrong?
this.onTouched();
}
}
}
模板
<ion-input [(ngModel)]="value"
(ionBlur)="onTouched()"
(ionChange)="onChange($event.target.value)">
</ion-input>
<ion-button (click)="openModal()">
Select from contacts
</ion-button>
问题:
ion-input
有ionChange
事件,因为你可以手动写一个电话号码。到目前为止很好。
如果你打开模态来选择一个电话号码,ionChange会被调用来让父节点知道这个变化,但是ion-input
的ionChange
也会被调用,因为这是一个变化。
示例
- 模板部分被省略,因为它不重要。*
export class ExamplePage implements OnInit {
form: FormGroup;
constructor(
private fb: FormBuilder
) {
}
ngOnInit(): void {
this.form = this.fb.group({
phoneNumber: [null, Validators.required]
});
this.form.get('phoneNumber').valueChanges.subscribe(() => this.doLogic());
}
// This is being called twice when choosing a phone number from the modal
doLogic() {
console.log('I was called');
}
}
我试过几种方法,但结果都一样。
我的目标是知道如何正确地实现这一点,只通知父母一次。
1条答案
按热度按时间mlmc2os51#
经过一段时间的调试问题,我发现我忘记了一件重要的事情的输入和事件的变化。
我有这个:
setter
this.newValue = phoneNumber
正在调用onChange()
,让它知道更改的父进程,但在此之后,ion-input
还有(ionChange)="onChange($event.target.value)
事件,它再次通知父进程。修复程序只是这样做:
这为
ion-input
设置了一个新值,ion-input
通过ionChange()
事件通知父进程,这样父进程只被通知一次。我不知道这是不是推荐的方法,但它确实有效。