标签: angular-reactive-forms

键入时进行 Angular 反应式表单验证

我正在处理此表单并希望在输入时进行验证。当前的行为是我选择输入,键入,当我单击其他站点时,它会显示错误。我认为当我设置控制、有效和脏时发生的错误,但我无法弄清楚。

打字稿

buildForm(): void {
 this.userForm = this.fb.group({
  'email': ['', [
    Validators.required,
    Validators.pattern('[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$')
  ]
  ],
  'password': ['', [
    Validators.required,
    Validators.minLength(6),
    Validators.maxLength(25)
   ]
   ],
 });
 this.userForm.valueChanges.subscribe(data => this.onValueChanged(data));
}

onValueChanged(data?: any) {
 if (!this.userForm) { return; }
 const form = this.userForm;
 for (const field in this.formErrors) {
  // clear previous error message (if any)
  this.formErrors[field] = '';
  const control = form.get(field);
  if (control && control.invalid && control.dirty) {
    const messages = this.validationMessages[field];
    for (const key in control.errors) {
      this.formErrors[field] += messages[key] …
Run Code Online (Sandbox Code Playgroud)

angular-material angular angular-reactive-forms angular-forms

6
推荐指数
2
解决办法
6391
查看次数

如何使用 Validator 和 Control Value Accessor 正确实现嵌套表单?

在我的应用程序中,我需要一个可重用的嵌套表单组件,例如Address。我希望自己AddressComponent处理自己的 FormGroup,这样我就不需要从外部传递它。在 Angular 会议(视频、演示)上,Angular Core 团队的一名成员 Kara Erikson 建议实现ControlValueAccessor嵌套表单,使嵌套表单实际上只是一个FormControl.

我还发现我需要实现Validator,以便主表单可以看到我的嵌套表单的有效性。

最后,我创建了嵌套表单需要扩展的 SubForm 类:

export abstract class SubForm implements ControlValueAccessor, Validator {

  form: FormGroup;

  public onTouched(): void {
  }

  public writeValue(value: any): void {
    if (value) {
      this.form.patchValue(value, {emitEvent: false});
      this.onTouched();
    }
  }

  public registerOnChange(fn: (x: any) => void): void {
    this.form.valueChanges.subscribe(fn);
  }

  public registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }

  setDisabledState(isDisabled: boolean): void {
    isDisabled …
Run Code Online (Sandbox Code Playgroud)

html javascript typescript angular angular-reactive-forms

6
推荐指数
1
解决办法
2778
查看次数

使用 Angular 反应式表单创建嵌套表单组

我在尝试实现嵌套的角度 FormGroup 时遇到了问题。

我正在使用描述表单输入的特定方案(客户端和服务器之间的接口)。我想创建一个具有某些验证的 FormGroup,并找到使用方案对象初始化 FormGroup 的最简单有效的方法。

方案对象属性本身就是对象,因此我想为其中的每一个创建自己的 FormGroup。此外,包含主 FormGroup 的组件包含应该连接到内部 FromGroups(方案对象的键)的子组件。

例如:

MySchema: {
  velocity: 
  {
    speed: number,
    direction: number
  },
  position: 
  {
    x: number,
    y: number
  }
}
Run Code Online (Sandbox Code Playgroud)

主窗体应该有 2 个内部组件 - 速度组件和位置组件。

每个子组件都应该连接到一个子表单组(速度组件到速度组等等)并显示相关的验证。

主窗体应连接到主 FormGroup。

这是一个小例子,在我们的项目中,架构要大得多,手动编写所有内部元素似乎是错误的。

我希望你能帮助我找到更好的方法。

谢谢。

更新

也许我的问题不够清楚..有没有办法将大对象转换为角度形式组/形式控件?

我的每个表单都包含我从服务器收到的对象,手动在 fb 中编写每个元素似乎是错误的。

再次感谢所有已经回答的人

angular angular-reactive-forms

6
推荐指数
1
解决办法
1万
查看次数

必须在索引处为表单控件提供一个值:1 - 错误

我正在使用带有 mat 自动完成功能的反应式表单。我在应用程序的其他部分使用了自动完成功能,但我无法弄清楚。我有一个formarray,每次我想在我的情况下添加一个新传感器时都会添加一个输入。自动完成在我的第一个输入中工作正常,但是当我尝试添加更多输入时显示错误:错误:必须在索引处为表单控件提供一个值:1

HTML:

<div class="row">
    <div class="input-field col s10">
      <div class="form-group">
        <div formArrayName="sensors_id">
          <div *ngFor="let sensor of addHomeboxPForm.get('sensors_id')['controls']; let i = index">
            <br>
            <input formControlName="{{i}}" type="text" placeholder="Select Sensor" aria-label="Number" matInput [matAutocomplete]="auto1">
            <mat-autocomplete autoActiveFirstOption #auto1="matAutocomplete" [displayWith]="displayWith" >
              <mat-option (onSelectionChange)="updateForm($event, [sensor.sensors_id], 'sensors_id')" *ngFor="let sensor of filteredOptionsS | async" [value]="sensor.sensor_serial">
                {{sensor.sensor_serial}}
              </mat-option>
            </mat-autocomplete>
            <div class="button-left">
              <button *ngIf="addHomeboxPForm.controls.sensors_id.value.length > 1" type="button" class="fa" (click)="onRemoveItem(i)">RemoveSensor</button>
            </div>
          </div>
        </div>
      </div>


<div class="input-field col s2">
        <button type="button" class="btn" (click)="onAddItem()">AddSensor</button>
      </div>
Run Code Online (Sandbox Code Playgroud)

TS:

格式数组: 'sensors_id': this.fb.array([], Validators.required),

  updateForm(ev: …
Run Code Online (Sandbox Code Playgroud)

angular angular-reactive-forms formarray mat-autocomplete

6
推荐指数
1
解决办法
3333
查看次数

如何对 ngControl 装饰有 @Self 的反应式组件进行单元测试

我通过注入 NgControl 编写了一个反应式组件,并使用 @Self 装饰器进行装饰。我的问题与此类组件的单元测试有关。请看下面的代码:

免责声明:我已经快速复制了代码并进行了一些内联更改。因此,这可能不是编译器满意的代码。

我的反应组件:

@Component({
  selector: 'text-input',
  templateUrl: '<input type="text" class="native_input" />'
})
class TextInput implements ControlValueAccessor {
  protected constructor(@Self() public controlDir: NgControl) {

    this.controlDir.valueAccessor = this;
  }

  // ...followed by other ControlValueAccessor methods

}
Run Code Online (Sandbox Code Playgroud)

单元测试:

describe('TextInput -', () => {

   let fixture: ComponentFixture<TextInputHost>;
   let textInput: TextInput;

   let inputElement: HTMLInputElement;

   beforeEach(async(() => {
     TestBed.configureTestingModule({
       declarations: [
         TextInput, TextInputHost
       ],
       imports: [
         FormsModule, ReactiveFormsModule
       ]
     });
  }));

  beforeEach(fakeAsync(() => {
    fixture = getTestBed().createComponent(TextInputHost);
    textInput = fixture.componentInstance.textInputComponent;
    textInput.writeValue('TestValue');
    inputElement …
Run Code Online (Sandbox Code Playgroud)

unit-testing angular-components angular angular-reactive-forms

6
推荐指数
1
解决办法
1886
查看次数

使用 ReactiveForms 和 NgbModal 时的 ExpressionChangedAfterItHasBeenCheckedError

我有一个反应式表单,当用户在输入中按下 ESC 键时,我想在表单隐藏之前显示一个“你确定”模式。
一旦显示模态,我就会在控制台中收到以下异常:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has 
changed after it was checked. Previous value: 'ng-untouched: true'. Current 
value: 'ng-untouched: false'.
Run Code Online (Sandbox Code Playgroud)

这是一个显示问题的 stackblitz(焦点输入并按 ESC)

注意:当您聚焦输入,模糊并再次聚焦时,问题不会再次出现ng-untouched变化。

有什么解决方法吗?实现此类功能的推荐方法是什么?

提前致谢!

ng-bootstrap angular angular-reactive-forms

6
推荐指数
1
解决办法
2950
查看次数

反应式表单:将表单组中的所有控件标记为脏

我有带表单的 Angular 6 应用程序。这是一个例子

export class ExampleComponent implements OnInit {
    form: FormGroup;

    constructor(private fb: FormBuilder) { }

    ngOnInit() {
        this.form = new FormGroup({
            first: new FormControl(),
            last: new FormControl()
        });

        this.markControlsAsDirty(this.form);
    }

    markControlsAsDirty(form: FormGroup) {
        this.form.get('first').markAsDirty();
        this.form.get('last').markAsDirty();
    }
}
Run Code Online (Sandbox Code Playgroud)

我不想获得单个控件并标记每个字段。我可以将表单组中的所有控件标记为脏吗?

更新我已经添加了stackblitz 示例来表明之前的两个答案是错误的

typescript angular angular-reactive-forms

6
推荐指数
3
解决办法
8046
查看次数

Angular 8:使 FormBuilder 只接受纬度和经度范围的数字

如何让 FormBuilder 要求数字?

我正在为纬度和经度编写表单构建器。在这下面,

  • 写入 -91 或 91 会产生验证错误,按预期工作
  • -90 和 90 之间的任何东西都很好。
  • 它接受最多 32 位数字和小数点的数字,也可以工作

问题:

  • 但是,输入字母“Abcd”等不会出现验证错误。

如何解决这个问题?

  'latitude': [null, [Validators.maxLength(32), Validators.min(-90), Validators.max(90)]],
Run Code Online (Sandbox Code Playgroud)

如果可能,最好在表单中进行验证,而不是输入文本框 type=number,

typescript angular-material angular angular-reactive-forms angular8

6
推荐指数
1
解决办法
4129
查看次数

在自定义 Angular 组件中访问 FormControl

我正在创建一个自定义角度组件,当我的 FormControl(反应式表单)无效时,它会显示错误工具提示。但我不知道如何访问自定义组件中的 FormControl 以检查它是否被标记为有效。

我想要完成的

<div [formGroup]="form">
     <input formControlName="name" type="text" />
     <custom-validation-message formControlName="name">My special error message!</custom-validation-message>
  </div>
Run Code Online (Sandbox Code Playgroud)

已经遇到的东西

错误错误:没有名称的表单控件的值访问器:'surveyType'

通过使用 NG_VALUE_ACCESSOR 实现 ControlValueAccessor 来修复此问题,即使我不想更改该值。我还添加了一个注入器来访问 NgControl。

import { Component, OnInit, Injector } from '@angular/core';
import { NgControl, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
    selector: 'custom-validation-message',
    templateUrl: './validation-message.component.html',
    providers: [{
        provide: NG_VALUE_ACCESSOR, multi: true, useExisting: ValidationMessageComponent
    }]
})
export class ValidationMessageComponent implements ControlValueAccessor, OnInit {
    public formControl: any;

    constructor(private injector: Injector) {
        super();
    }

    public ngOnInit(): void {
        const model = this.injector.get(NgControl); …
Run Code Online (Sandbox Code Playgroud)

angular-components angular angular-reactive-forms

6
推荐指数
1
解决办法
4781
查看次数

从不同的表单组更新表单组表单控件值,但我不想永久更改这些值(角度)

将鼠标悬停在表中的第一列上时,会出现一个工具提示,单击按钮会打开包含编辑 json 部分的对话框。

我提供了 2 个功能:-

[请从对话框的左侧部分选择一行]

1) 可以编辑 json(在这种情况下,用户单击左侧部分的行,开始编辑 json,并且在不恢复新更改的情况下,用户单击左侧部分下的不同行,然后再次选择先前选择的行原始 json数据被保留)

2) 用户单击左侧部分的行,并开始从输入字段提供输入(出现在“添加为”按钮上方)我开始更新“编辑 Json”部分中的“mTitle”键,因此一旦用户点击另一个行并再次返回到先前选择的行,json 'mTitle' 键不显示原始(旧)值

预期行为

我期待的是一旦用户提供输入,'mTitle' 键应该被更新(这是有效的)但是在 Add As New 按钮被点击或用户点击后,'mTitle' 键应该再次保留其旧值在另一行。(与情况 1 相同的行为)

Stackblitz 链接 https://stackblitz.com/edit/angular-mat-tooltip-v6m2tz?file=app%2Falert-dialog%2Falert-dialog.component.ts

请建议

警报对话框.component.html

<form [formGroup]="jsonform">
            <json-input formControlName="json" name="result"></json-input>
</form>

 <form [formGroup]="submitJsonNameAndForm" class="">
    <mat-form-field [floatLabel]="'never'" class="alertinput">
        <input matInput trim type="text" #alertnamefieldRef formControlName="alertnamefield" placeholder="Custom Alert Name"
            autocomplete="off" (keyup) = "passingAlerTitle(alertnamefieldRef?.value)">
    </mat-form-field>
</form>
Run Code Online (Sandbox Code Playgroud)

警报对话框.component.ts

passingAlerTitle(event){
    this.data.data[this.selectedId].conditionals.alert.mTitle = event;
    this.jsonform.setValue({
      json: this.data.data[this.selectedId].conditionals
     });  
}
Run Code Online (Sandbox Code Playgroud)

javascript angular angular-reactive-forms angular-forms

6
推荐指数
1
解决办法
1286
查看次数