反应式表单:如何使用 Angular WITHOUT [(ngModel)] 上的 FormControl 将输入值捕获到组件内的变量中?

Reactive form: How to capture the input value into a variable within component using FormControl on Angular WITHOUT [(ngModel)]?

我的网络应用前端 Angular 上有一个简单的文本输入,它接受用户名:

1
2
3
4
5
6
7
8
<mat-form-field>
      <mat-label>Chosen Name:</mat-label>
      <input name="chosenName" formControlName="chosenName" [(ngModel)]="chosenName" matInput type="text" placeholder="JOHN DOE"/>
      <mat-hint align="end">REQUIRED FIELD!</mat-hint>
      <mat-error *ngIf="hasNameError('chosenName', 'required')"
        >Minimum and Maxmimum of length 12 is required!</mat-error
      >
    </mat-form-field>

我使用 formGroup 是因为我打算在这个 div 中添加更多输入字段,只是想让这个输入首先工作。

我使用 [(ngModel)]="chosenName" 捕获输入值并将其分配给我的组件类 (this.chosenName) 中的变量。

下面是我的组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Component({
  selector: 'app-user',
  templateUrl: './userInput.component.html',
  styleUrls: ['./userInput.component.scss']
})
export class UserInputEnquiry implements OnInit {
  title = 'Welcome to this note-taking app!';
  chosenName: string;
  enquiryByUserInputForm: FormGroup;

  constructor() {}

  ngOnInit() {
    this.enquiryByUserInputForm = new FormGroup({
      chosenName: new FormControl('', [Validators.required, Validators.minLength(9), Validators.maxLength(9)])
    });
  }

  public hasLengthError = (controlName: string, errorName: string) => {
    return this.enquiryByUserInputForm.controls[controlName].hasError(errorName);
  };

  onSubmit() {
      console.log(this.chosenName);
  }

}

根据我上一个问题的回答,我被告知不要使用 [(ngModel)],因为 FormControl 已经包含输入捕获并且我收到了一个非常严重的警告,但怎么会呢?

如果我从输入中删除 [(ngModel)]="chosenName",则永远不会为 this.chosenName 捕获输入,并且控制台会记录一个空白/未定义的输出。我在这里有什么遗漏吗?


如果你想要任何初始值,那么用那个初始化 chosenName

1
chosenName: string = '';

然后你可以用这个值初始化表单:

1
2
3
this.enquiryByUserInputForm = new FormGroup({
  chosenName: new FormControl(this.chosenName, [Validators.required, Validators.minLength(9), Validators.maxLength(9)])
});

提交时,您可以使用以下命令访问所有表单值:

1
2
3
  onSubmit() {
      console.log(this.enquiryByUserInputForm.value);
  }

要获得特定的控制值,你可以这样做:

1
2
3
  onSubmit() {
      console.log(this.enquiryByUserInputForm.get('chosenName').value);
  }

编辑:
chosenName 类属性可以完全省略,因为它只是用于初始化,您可以在创建表单时直接执行此操作。


Best approach to capture input value into a variable in Angular
reactive form:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
chosenName: string = '';

ngOnInit() {
    this.enquiryByUserInputForm = this.formBuilder.group({
        chosenName: new FormControl(null, [Validators.required, Validators.minLength(9), Validators.maxLength(9)])
    });
}

get getFc() {
    return this.enquiryByUserInputForm.controls;
}

onSubmit() {
    this.chosenName = this.getFc['chosenName'].value
    console.log(this.chosenName);
}

如果您使用的是 ReactiveFormsModule,您可以订阅值更改。

1
this.userNameFormGroupEnquiry.valueChanges.subscribe(values => do something)

values 将是一个对象,其中 { formcontrolname: valueofinput}

每当任何输入发生变化时都会触发,太频繁了。所以你可以做一些事情来控制事情。

1
2
3
4
5
this.userNameFormGroupEnquiry.valueChanges.pipe(
     filter(() => this.userNameFormGroupEnquiry.valid &&
                  this.userNameFormGroupEnquiry.dirty),
     debounceTime(1000))
    .subscribe(values => do something)

这会检查表单中的更改和有效性,并消除抖动;这意味着它将在最后一次击键后发出一秒钟。这仍然经常触发,您还可以做另一件事。

当您定义表单控件时,您可以执行以下操作:

1
2
3
4
5
this.userNameFormGroupEnquiry = new FormGroup( {
    chosenName: new FormControl('', { updateOn: 'blur', validators:
              Validators.required }),
    ...
    })

updateOn 可以设置为'change' | '模糊' | '提交'。

在复杂且大型的形式中,这很容易变成消防软管,但有一些选项可用于将流量限制在可管理的范围内。