【问题标题】:how to listen of angular template driven form changes如何监听角度模板驱动的表单更改
【发布时间】:2018-02-07 09:44:36
【问题描述】:

以我的形式:

<form>
   <label class="form-check-label">
     <input [(ngModel)]="options.o1" name="o1"
            type="checkbox" class="form-check-input" >
     Option 1
   </label>
   <label class="form-check-label">
     <input [(ngModel)]="options.o2" name="o2"
            type="checkbox" class="form-check-input" >
     Option 2
   </label>
</form>

我希望在两个复选框之一发生更改时得到通知,而不是通过向每个复选框添加事件处理程序,而是通过向表单添加事件处理程序,实际上表单中有更多字段。

【问题讨论】:

    标签: javascript angular


    【解决方案1】:

    您可以获取NgForm 指令,例如:

    html

    <form #form="ngForm">
       ...
    </form>
    

    ts

    @ViewChild('form') ngForm: NgForm;
    

    对于 Angular 9 及更高版本,您应该使用 static: true 选项:

    @ViewChild('opportunityForm', { static: true }) ngForm: NgForm;
    

    然后在NgForm.form上收听valueChanges

    ts

    ngOnInit() {
      this.formChangesSubscription = this.ngForm.form.valueChanges.subscribe(x => {
        console.log(x);
      })
    }
    
    ngOnDestroy() {
      this.formChangesSubscription.unsubscribe();
    }
    

    ng-run demo

    【讨论】:

    • 顺便说一句,你忘记取消订阅了吗?
    • 并且在任何用户进行更改之前也会记录初始化。也许我必须添加一个超时。
    • 好吧,最后我用了一个 ReactiveForm
    • 就我而言,我必须使用属性read: @ViewChild('inputField', { read: NgControl }) inputField: NgControl;
    • @ViewChild('form', { static: true }) ngForm: NgForm; 自角度 8
    【解决方案2】:

    我使用了公认的答案,并以此为基础创建了一个值得关注的演示版本。

    TS 文件

    export class AppComponent {
      
      options: any;
      formChangesSubscription: any;
      @ViewChild('form') ngForm: NgForm;
    
      updated: any;
    
      constructor() {
        this.options = { o1: true, o2: false }
      }
    
      ngOnInit() {
        this.formChangesSubscription = this.ngForm.form.valueChanges.subscribe(form => {
          console.log(form);
          this.updated = form;
        })
      }
    
      ngOnDestroy() {
        this.formChangesSubscription.unsubscribe();
      }
    }
    

    HTML 文件

    <form #form="ngForm">
      <label class="form-label">
         <input [(ngModel)]="options.name" name="name"
                type="text" class="form-input" >
         
       </label>
       <label class="form-check-label">
         <input [(ngModel)]="options.o1" name="o1"
                type="checkbox" class="form-check-input" >
         Option 1
       </label>
       <label class="form-check-label">
         <input [(ngModel)]="options.o2" name="o2"
                type="checkbox" class="form-check-input" >
         Option 2
       </label>
    </form>
    
    <label>{{updated?.o1}}</label>
    <label>{{updated?.o2}}</label>
    <label>{{updated?.name}}</label>
    

    https://stackblitz.com/edit/angular-change-template-form?file=src/app/app.component.ts

    【讨论】:

      【解决方案3】:

      你应该使用@Remify 提到的反应形式,然后你可以试试这个:

      this.form.valueChanges.subscribe(() => {
           console.log('form changed');
      });
      

      要使用反应形式检查角度文档:

      https://angular.io/guide/reactive-forms

      【讨论】:

      • 据我所知,不要忘记取消订阅此订阅,因为它会导致内存泄漏。在 ngOnDestroy() 上执行此操作。这种订阅不同于不需要取消订阅的 http 订阅。
      【解决方案4】:

      我有个坏消息要告诉你:使用响应式表单。它们正是您所描述的。

      【讨论】:

      • 我同意反应式更好。但对于 op 这意味着更多的工作。
      • NgForm 下使用了一种反应形式。所以你只需要抓住它的form 然后你就可以做任何反应式表单应用程序可以做的事情。 (yurzui 是对的)
      • 要么在组件内部使用 @ViewChild() 对模板变量#form 的引用,要么使用响应式表单。因此,答案是错误的。这取决于您的要求以及您需要对表单的控制程度。
      猜你喜欢
      • 2021-02-18
      • 2018-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-23
      • 2021-05-31
      • 2021-01-03
      • 1970-01-01
      相关资源
      最近更新 更多