[英]Angular Reactive Forms valueChanges - UI changes only
The Angular FormControl
has a valueChanges
Observable that states: Angular
FormControl
有一个valueChanges
Observable 声明:
Emits an event every time the value of the control changes, in the UI or programmatically.
每当控件的值在 UI 中或以编程方式更改时发出一个事件。
Is there a way to set the FormControl to ignore programmatic value changes?有没有办法将 FormControl 设置为忽略编程值更改? (Basically the equivalent of
OneWayToSource
binding in .NET) (基本上等同于 .NET 中的
OneWayToSource
绑定)
Specifically, the issue I'm facing is that my valueChanges
subscription, I'm updating a bunch the values bound to a bunch of other controls, which then causes valueChanges
to fire for all of them as well, which is problematic as the actions they perform in their valueChanges
handlers conflicts with the control the user actually touched.具体来说,我面临的问题是我的
valueChanges
订阅,我正在更新一堆绑定到一堆其他控件的值,然后导致valueChanges
也为所有这些控件触发,这是有问题的,因为它们的操作在他们的valueChanges
处理程序中执行与用户实际触摸的控件冲突。
You can skip emitting the valueChange event by passing the option { emitEvent: false }
to the setValue
call.您可以通过将选项
{ emitEvent: false }
传递给setValue
调用来跳过发出 valueChange 事件。
setValue(value: any, options: {
onlySelf?: boolean;
emitEvent?: boolean;
emitModelToViewChange?: boolean;
emitViewToModelChange?: boolean;
} = {}): void
Also you might want to take a look at other options.此外,您可能还想看看其他选项。
If onlySelf is true, this change will only affect the validation of this FormControl and not its parent component.
如果 onlySelf 为 true,则此更改只会影响此 FormControl 的验证,而不影响其父组件。 This defaults to false.
这默认为 false。
If emitEvent is true, this change will cause a valueChanges event on the FormControl to be emitted.
如果emitEvent 为true,则此更改将导致在FormControl 上发出一个valueChanges 事件。 This defaults to true (as it falls through to updateValueAndValidity).
这默认为 true(因为它属于 updateValueAndValidity)。
If emitModelToViewChange is true, the view will be notified about the new value via an onChange event.
如果emitModelToViewChange 为true,将通过onChange 事件通知视图新值。 This is the default behavior if emitModelToViewChange is not specified.
如果未指定emitModelToViewChange,这是默认行为。
If emitViewToModelChange is true, an ngModelChange event will be fired to update the model.
如果emitViewToModelChange 为true,将触发ngModelChange 事件以更新模型。 This is the default behavior if emitViewToModelChange is not specified.
如果未指定emitViewToModelChange,这是默认行为。
The reactive form group have property yourFormName.pristine反应式表单组具有属性 yourFormName.pristine
You can use !yourFormName.pristine to detect only UI changes您可以使用 !yourFormName.pristine 仅检测 UI 更改
* A control is `pristine` if the user has not yet changed
* the value in the UI.
*
* @returns True if the user has not yet changed the value in the UI; compare `dirty`.
* Programmatic changes to a control's value do not mark it dirty.
*/
readonly pristine: boolean;
You can pass { emitEvent: false }
as options for the below reactive form methods to prevent them from triggering the valueChanges event您可以传递
{ emitEvent: false }
作为以下反应式表单方法的选项,以防止它们触发 valueChanges 事件
this.form.patchValue(value, { emitEvent: false })
this.form.setValue(value, { emitEvent: false })
this.form.controls.email.updateValueAndValidity({ emitEvent: false })
this.form.disable({ emitEvent: false })
yes disable triggers the valueChanges event yes disable 触发 valueChanges 事件
PS: above this.form
is a reactive form PS:上面的
this.form
是一个reactive form
Read this excellent post, it'll answer all your questions and even give some great insights on reactive forms:阅读这篇优秀的文章,它会回答你所有的问题,甚至对反应式形式给出一些很好的见解:
https://netbasal.com/angular-reactive-forms-tips-and-tricks-bb0c85400b58 https://netbasal.com/angular-reactive-forms-tips-and-tricks-bb0c85400b58
That may be helpful:这可能有帮助:
yourControl.valueChanges.pipe(
filter(() => yourControl.touched)
).subscribe(() => {
....
})
It will fire only if control was previously touched.仅当先前触摸控件时才会触发。 It doesnt fix all the issues, but may solve some cases.
它并不能解决所有问题,但可以解决某些情况。
I could do it by putting this listener on the html file:我可以通过将此侦听器放在 html 文件中来做到这一点:
<ss-multiselect-dropdown ... (ngModelChange)="functionToTrigger($event)"></ss-multiselect-dropdown>
And on the .ts file:在 .ts 文件上:
functionToTrigger($event) {
if (event === undefined) {
// Put here are the instructions for UI changes
} else {
// Put here are the instructions for programmatic changes
}
I really don't know why it works this way.我真的不知道为什么它会这样工作。 I came to this solution by trial and error.
我通过反复试验得出了这个解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.