【问题标题】:Angular Reactive Forms valueChanges - UI changes onlyAngular Reactive Forms valueChanges - 仅 UI 更改
【发布时间】:2018-04-16 15:43:34
【问题描述】:

Angular FormControl 有一个 valueChanges Observable 声明:

每当控件的值在 UI 中或以编程方式发生变化时,都会发出一个事件。

有没有办法将 FormControl 设置为忽略编程值更改? (基本上相当于.NET中的OneWayToSource绑定)

具体来说,我面临的问题是我的valueChanges 订阅,我正在更新一堆绑定到一堆其他控件的值,然后导致valueChanges 也为所有这些控件触发,这是有问题的,因为他们在valueChanges 处理程序中执行的操作与用户实际触摸的控件冲突。

【问题讨论】:

    标签: angular angular-reactive-forms


    【解决方案1】:

    您可以通过将选项 { emitEvent: false } 传递给 setValue 调用来跳过发出 valueChange 事件。

    setValue(value: any, options: {
        onlySelf?: boolean;
        emitEvent?: boolean;
        emitModelToViewChange?: boolean;
        emitViewToModelChange?: boolean;
    } = {}): void
    

    您可能还想看看其他选项。

    如果 onlySelf 为 true,则此更改将仅影响此 FormControl 的验证,而不影响其父组件。这默认为 false。

    如果 emitEvent 为 true,此更改将导致 FormControl 上的 valueChanges 事件被发出。这默认为 true(因为它属于 updateValueAndValidity)。

    如果 emitModelToViewChange 为 true,视图将通过 onChange 事件通知新值。如果未指定 emitModelToViewChange,这是默认行为。

    如果 emitViewToModelChange 为 true,则会触发 ngModelChange 事件来更新模型。如果未指定 emitViewToModelChange,这是默认行为。

    Docs

    【讨论】:

    • 谢谢,这很有帮助。但是,在我的特定情况下,我将值 bound 更新到其他表单控件,而不是表单控件本身。所以我没有可用的 setValue 方法,而且似乎 Angular 的更改检测正在接受更改并触发事件。
    【解决方案2】:

    您可以将{ 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 })
    

    是的,禁用触发 valueChanges 事件

    PS:以上this.form是一种反应形式

    阅读这篇精彩的文章,它会回答你所有的问题,甚至对反应式表单提供一些深刻的见解:

    https://netbasal.com/angular-reactive-forms-tips-and-tricks-bb0c85400b58

    【讨论】:

      【解决方案3】:

      反应式表单组具有属性 yourFormName.pristine

      您可以使用 !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;
      

      【讨论】:

      • pristine/dirty 在后续 patchValue's 之后不会重置,是吗?
      【解决方案4】:

      我可以通过将此监听器放在 html 文件中来做到这一点:

      <ss-multiselect-dropdown ... (ngModelChange)="functionToTrigger($event)"></ss-multiselect-dropdown>
      

      在 .ts 文件上:

      functionToTrigger($event) {
          if (event === undefined) {
              // Put here are the instructions for UI changes
          } else {
              // Put here are the instructions for programmatic changes
      }
      

      我真的不知道为什么会这样。我通过反复试验得出了这个解决方案。

      【讨论】:

      • ngModelChange中传入的$event就是模型的值。它与模型在 UI 中如何更改无关。
      猜你喜欢
      • 2019-08-13
      • 2018-09-21
      • 1970-01-01
      • 2018-08-24
      • 2017-05-06
      • 1970-01-01
      • 2019-06-22
      • 2020-07-24
      • 2019-11-23
      相关资源
      最近更新 更多