【问题标题】:Angular manually update ngModel and set form to dirty or invalid?Angular 手动更新 ngModel 并将表单设置为脏或无效?
【发布时间】:2018-05-15 07:20:23
【问题描述】:

我有这样的表单和底层模型

来自组件

myTextModel: string;
updateMyTextModel(): void {
    this.myTextModel = "updated model value";
    //todo- set form dirty (or invalid or touched) here
}

HTML 模板

<form #testForm="ngForm" id="testForm">
  <input type="text" id="myText" [(ngModel)]="myTextModel" name="myText" #myText="ngModel">
</form>
<button (click)="updateMyTextModel()">Update myTextModel</button>
<div *ngIf="testForm.dirty">testForm diry</div>
<div *ngIf="testForm.touched">testForm touched</div>

如何从代码中设置触碰或弄脏的表单?

注意:在这个例子中,我使用一个按钮来触发模型更改,但我也可能以其他方式更新模型,例如在来自 web api 异步请求的回调中。

【问题讨论】:

    标签: angular typescript angular4-forms


    【解决方案1】:

    如果您需要遍历表单中的所有输入字段并将它们标记为已触摸或脏:

    onSubmit(nameForm)
    {
        let inputAryVar = nameForm.form.controls
        for(let keyVar in inputAryVar)
        {
            inputAryVar[keyVar].markAsTouched();
            inputAryVar[keyVar].markAsDirty();
        }
    }
    

    【讨论】:

      【解决方案2】:

      如果你通过类似这样的方式使用NgForm form ref -

      @ViewChild('viewChildForm') public viewChildForm: NgForm; 并尝试在.ts 文件中以编程方式更改表单:

      • 将表单设置为无效:this.viewChildForm.form.setErrors({ 'invalid': true });

      • 设置为有效:this.viewChildForm.form.setErrors(null);

      【讨论】:

        【解决方案3】:

        为什么不使用响应式表单 (FormGroup),

        let testForm = new FormGroup({
            myText: new FormControl('initial value')
        })
        
        <form [formGroup]="testForm">
            <input type="text" formControlName="myText">
        </form>
        
        <button (click)="updateMyTextModel()">Update myTextModel</button>
        <div *ngIf="testForm.dirty">testForm diry</div>
        <div *ngIf="testForm.touched">testForm touched</div>
        

        在你的函数中,你可以根据你想要的任何条件使用markAsDirty()

        updateMyTextModel(): void {
            this.myTextModel = "updated model value";
            if ( // some condition ) {
                this.testForm.markAsDirty();
            }
        }
        

        要将单个表单控件设置为脏/已触摸,您可以使用

        this.testForm.get('myText').markAsDirty();
        this.testForm.get('myText').markAsTouched();
        

        【讨论】:

          【解决方案4】:

          解决方案:

          //our root app component
          import {Component, NgModule, VERSION} from '@angular/core'
          import {BrowserModule} from '@angular/platform-browser'
          import { Component, ViewChild } from '@angular/core';
          import { FormsModule }   from '@angular/forms';
          
          @Component({
            selector: 'my-app',
            template: `
              <form #testForm="ngForm" id="testForm">
                  <input type="text" id="myText" [(ngModel)]="myTextModel" name="myText" #myText="ngModel">
              </form>
              <button (click)="updateMyTextModel()">Update myTextModel</button>
              <div *ngIf="testForm.dirty">testForm diry</div>
              <div *ngIf="testForm.touched">testForm touched</div>
            `,
          })
          export class App {
          
            @ViewChild('testForm') test: any;
          
            updateMyTextModel(){
              this.test.control.markAsTouched();
              this.test.control.markAsDirty();
          
            }
          
            constructor() {
              console.log(this.test);
            }
          }
          
          @NgModule({
            imports: [ BrowserModule,FormsModule ],
            declarations: [ App ],
            bootstrap: [ App ]
          })
          export class AppModule {}
          

          Plunkr 工作:

          https://plnkr.co/edit/YthHCEp6iTfGPVcNr0JF?p=preview

          【讨论】:

          • this.test.control.markAsDirty() 是否仍然适用于 Angular 10?
          • @ajgo 是的。我用过那个
          【解决方案5】:

          这应该可行:

          @ViewChild('testForm') testForm;
          
          
          updateMyTextModel(): void {
              this.myTextModel = "updated model value";
              this.myForm.form.markAsDirty();
          }
          

          【讨论】:

          • form.form ... 角,角 ^^
          猜你喜欢
          • 2018-01-12
          • 2017-09-19
          • 1970-01-01
          • 2018-03-11
          • 1970-01-01
          • 2018-09-25
          • 2017-10-26
          • 2014-08-27
          • 1970-01-01
          相关资源
          最近更新 更多