即使表单未通过验证,组件加载时反应形式的Angular 7设置值也会启用保存按钮

时间:2018-11-20 07:01:49

标签: angular angular6 angular-reactive-forms angular7

我有以下问题。 Click to check the stack blitz

我正在构造函数中设置反应形式:

this.formGroup = this.fb.group({
      'family_name_en': new FormControl('', Validators.required),
      'family_name_ar': new FormControl('', [Validators.required, Validators.pattern('[\u0600-\u06FF ]*')]),
      'unit_id': new FormControl({ value: '', disabled: true }, [Validators.required])
});

ngOnInti()钩子中,我正在获取与unit_id相关的数据。

当我将数据从平台迁移到另一个平台时,不建议使用阿拉伯语的姓氏,但现在是这样。因此,大多数数据将在不使用阿拉伯文名称的情况下加载。

问题在于按钮始终处于启用状态,而我需要做的是,如果用户想更新此unit_id,则他应该添加阿拉伯语名称,以便随后启用按钮。

如果表单有效,则启用按钮在加载组件时不会造成伤害。

这里是getData()方法,用于获取数据并设置表单组控件的值:

ngOnInit() {
    this.getDataById();
}

getDataById():

getDataById() {
    this.showSpinner = true;
    this.auth.getDataById(this.unit_id).subscribe(
      (data) => {
        if (data['info'][0]['total'] == 1) {
          this.noDataBool = false;
          this.showSpinner = false;
          this.family_name_en = data['info'][0]['hh_last_name_en'];
          this.formGroup.controls['family_name_en'].setValue(this.family_name_en);
          this.family_name_ar = data['info'][0]['hh_last_name_ar'];
          this.formGroup.controls['family_name_ar'].setValue(this.family_name_ar);
          this.unit_id = data['info'][0]['unit_id'];
          this.formGroup.controls['unit_id '].setValue(this.unit_id);
    }
}

按钮:

<button mat-raised-button color="warn" (click)="updateData()" [disabled]="!formGroup.valid">
    <mat-icon>update</mat-icon>Update
</button>

2 个答案:

答案 0 :(得分:4)

您应该在FormControl API上使用controls API,而不是通过在formGroup上使用get直接访问import { Component } from '@angular/core'; import { FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms'; import { Observable } from 'rxjs/Observable'; @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { formGroup: FormGroup; titleAlert: string = 'This field is required'; post: any = ''; family_name_en; family_name_ar; unit_id; constructor(private fb: FormBuilder) { } ngOnInit() { this.formGroup = this.fb.group({ 'family_name_en': new FormControl('', Validators.required), 'family_name_ar': new FormControl('', [Validators.required, Validators.pattern('[\u0600-\u06FF ]*')]), 'unit_id': new FormControl({ value: '', disabled: true }, [Validators.required]) }); this.getDataById(); } getDataById() { let data: Array<any> = [ 'Ali', '', '123' ] this.family_name_en = data[0]; this.formGroup.get('family_name_en').setValue(this.family_name_en); this.family_name_ar = data[1]; this.formGroup.get('family_name_ar').setValue(this.family_name_ar); this.unit_id = data[2]; this.formGroup.get('unit_id').setValue(this.unit_id); } } 。这将为您提供更多控制权并显着清理实现(尤其是在嵌套元素很深的情况下)。您可以像这样更改组件实现:

علي

这是您的推荐人Updated StackBlitz。您可以通过在其中键入Ali来进行测试,以启用“更新”按钮。键入from itertools import chain import fnmatch paths = ('/path/to/directory/one/', '/path/to/directory/two/', 'etc.', 'etc.') file1 = [] file2 = [] for path, dirs, files in chain.from_iterable(os.walk(path) for path in paths): for file in files: if file in fnmatch.filter(files, '*1*.csv'): file1.append(file) if file in fnmatch.filter(files, '*2*.csv'): file2.append(file) To create your dataframes you would do something like this; df_file1 = pd.concat([pd.DataFrame(pd.read_csv(file1[0], sep=';')), pd.DataFrame(pd.read_csv(file1[1], sep=';'))], ignore_index=True) df_file2 etc. 将使其保持禁用状态。

答案 1 :(得分:1)

在这种情况下,我总是使用以下代码:

this.family_name_ar.setValue(data['info'][0]['hh_last_name_ar']);
this.family_name_ar.updateValueAndValidity();

通过调用第二种方法updateValueAndValidity(),我们告诉Angular

  

重新计算控件的值和验证状态。

有关Angular Docs的更多信息。

现在,如果data['info'][0]['hh_last_name_ar']为空,则应该禁用该按钮,并且表单无效。

您可以将上述方法用于所需的每个字段。