标签: angular-reactive-forms

Angular:在更改另一个表单控件时触发表单控件验证

请在此处参考 stackblitz 中的项目 。

可以看出,我的反应形式的控件为firstNumber、secondNumber和thirdNumber。我需要对表单控件进行验证thirdNumber,使其值不应大于在firstNumber和之间具有最小值的表单控件的值secondNumber。

validateThirdNumber每当表单控件发生更改时,组件中的自定义验证器都可以正常工作thirdNumber,但我需要对表单控件的更改进行验证firstNumber,secondNumber因为验证逻辑也可以根据表单控件的更改 firstNumber而更改secondNumber。

为此,我添加了一个有关表单控件更改的事件firstNumber,并将secondNumber表单控件标记thirdNumber为touched但其验证似乎没有被触发。

那么,如何在表单控件thirdNumber发生变化时触发表单控件firstNumber的验证secondNumber?

另外,为什么this.myFormGroup有时在自定义验证器中未定义(请参阅登录于app.componen.ts)line:22,即使在绑定this到其表单控件声明并this.myFormGroup在 中定义后也是如此 constructor ?

angular angular-reactive-forms angular-custom-validators

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

对 FormGroup 进行更改后,如何在单元测试中触发 valueChanged 可观察对象?

我正在一个包含反应式表单 (FormGroup) 和 valueChanges 订阅的组件上编写单元测试代码,但我还没有弄清楚如何确保 FormGroup 发出 valueChanges 事件。

// In the component under test:
this.formGroup.get('field').valueChanges
     .subscribe((obj: any[]) => {
         debugger; // BREAKPOINT
         dataObject.fieldValues = [ ... ];
         ... details here should be unimportant ...
     });

// In the unit test:
it('should set dataObject from field component', fakeAsync(() => {
        [
    values: string[] = [ ... ];

    component.formGroup.get('field').setValue(values);
    component.formGroup.get('field').updateValueAndValidity({ emitEvent: true });
    fixture.detectChanges();
    tick();

    expect(component.dataObject.fieldValues.length).toEqual(values.length);

}));

Run Code Online (Sandbox Code Playgroud)

我无法让单元测试规范命中组件订阅代码中的断点。

unit-testing angular angular-reactive-forms

5
推荐指数
1
解决办法
7975
查看次数

触发 Angular 异步 FormGroup 验证

背景

仅当该组及其所有子项的所有同步验证均有效时,才会执行 FormGroup 上的异步验证。

问题

我想在所有子项都有效之前在 FormGroup 上执行 asyncValidator。

this.myForm = new FormGroup({
  country: [ null, [ Validators.required ] ],
  postalCode: [ null ],
  unrelatedField1: [ null ],
  unrelatedField2: [ Validators.min(123) ]
}, {
  validators: [ postalCodeFormat ],
  asyncValidators: [ postalCodeExists ]
})
Run Code Online (Sandbox Code Playgroud)

我的自定义 postalCodeExists 验证器需要国家/地区和邮政编码字段。它不关心“unrelatedField2”的有效性。

有什么方法可以手动触发 FormGroup 的异步验证吗?

我的第一个想法

据我所知这是不可能的。

this.myForm.valueChanges.pipe(
  map(...etc),
  distinctUntilChanges(...etc)
).subscribe(() => {
  if (this.myForm.get('country').valid && this.myForm.get('postalCode').valid) {
    this.myForm.executeAsyncValidationPlease();
  }
});
Run Code Online (Sandbox Code Playgroud)

我的第二个想法

this.myForm = new FormGroup({
  countryAndPostalCodeGroup: new FormGroup({
    country: [ null, [ Validators.required ] ], …
Run Code Online (Sandbox Code Playgroud)

angular angular-reactive-forms

5
推荐指数
0
解决办法
1164
查看次数

角度反应形式验证嵌套字段

我正在使用Angular 7

我有一个嵌套的反应形式

this.salonProfileForm = this.fb.group({
  salonName: new FormControl('', [Validators.required]),
  address: this.fb.group({
    city: new FormControl('', [Validators.required])
  })
});

get f() {
    return this.salonProfileForm.controls;
}
Run Code Online (Sandbox Code Playgroud)

我有这样的 HTML 表单

<input type="text" formControlName="salonName" required />
<ng-container *ngIf="submitted && f.salonName.invalid && (f.salonName.dirty || f.salonName.touched)">
   <small *ngIf="f.salonName.errors.required">
      Salon name is required
   </small>
</ng-container>

<div formGroupName="address">
  <input type="text" formControlName="city" />
  <ng-container *ngIf="submitted && f.city.invalid && (f.city.dirty || f.city.touched)">
    <small *ngIf="f.city.errors.required">
        city is required
    </small>
  </ng-container>
</div>
Run Code Online (Sandbox Code Playgroud)

但这会在城市输入ng-container字段上产生错误,如下所示

ERROR TypeError: Cannot read property 'invalid' …
Run Code Online (Sandbox Code Playgroud)

angular angular-reactive-forms

5
推荐指数
1
解决办法
6041
查看次数

当构造时值发生变化时,表单因异步验证器而陷入 PENDING 状态

当在表单组上使用带有异步验证器的反应式表单时,如果通过patchValue在构造函数或 in 中使用来更改表单组的值ngOnInit- 即使异步验证器可观察完成,表单仍保持PENDING状态。

我在Stackblitz中创建了一个SSCCE

在示例中,您会看到一个包含两个字段的简单表单,其中指示表单状态和验证器状态。在代码中,ngOnInit我调用patchValue表单,导致表单进入PENDING状态,并调用异步验证器。

异步验证器没有做太多事情,它只是等待 1 秒,然后返回一个null错误对象,基本上表明表单是有效的。您可以在指示中看到验证已完成,但表单仍保持PENDING状态。

ngOnInit如果您在构造函数或对象构造之外的任何时间触发字段值的更改,那么VALID当验证程序完成时,表单会进入状态。如果您将值更改包装在 中,这也适用setTimeout。

难道我做错了什么?这是正常行为,还是 Angular 中的错误?

angular angular-reactive-forms angular-custom-validators

5
推荐指数
1
解决办法
5888
查看次数

动态添加行:Angular Reactive-Form

我想在单击 时动态添加行button。我为此使用反应形式。 这就是我要说的

这是我的 html 代码

<table>
    <thead>
        <tr class='tableHeader'>
            <div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
                <td fxFlex="22" class="pr-4">Name</td>
                <td fxFlex="15" class="pr-4">Price</td>
                <td fxFlex="15" class="pr-4">Loan Term</td>
                <td fxFlex="15" class="pr-4">Quantity</td>
                <td fxFlex="15" class="pr-4">Deposit</td>
                <td fxFlex="15" class="pr-4">Total</td>
            </div>
        </tr>
    </thead>
    <tbody>
        <tr [formGroup]="loanProductForm">
            <div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
                <td fxFlex="22">
                    <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                        <mat-label>Product </mat-label>
                        <mat-select formControlName="productId" required>
                            <mat-option *ngFor="let product of productList" [value]="product.productId">
                                {{product.name}}
                            </mat-option>
                        </mat-select>
                    </mat-form-field>
                </td>
                <td fxFlex="15">
                    <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                        <mat-label>Price </mat-label> …
Run Code Online (Sandbox Code Playgroud)

javascript angular angular-reactive-forms

5
推荐指数
1
解决办法
4212
查看次数

Angular:在异步调用和 AsyncPipe 后创建动态反应表单

我执行异步服务调用来获取元素列表。

 public elementList: Array<Element>;
   ... 
   this.service.getElementList().subscribe( list => {
       this.elementList = list;
       this.createFormGroup(list);
     }
   );
   ...
Run Code Online (Sandbox Code Playgroud)

当我收到元素列表(我订阅了服务调用)时,我根据元素列表构建表单组。在模板中,我有一个 *ngIf 仅当列表大于零时才绘制。

*ngIf="elementList?.length>0"
Run Code Online (Sandbox Code Playgroud)

由于elementList是异步获取的,所以这个ngIf不起作用。我读到可以将 ngIf 与 AsnycPipe 一起使用。所以在模板中我将有:

*ngIf="elementList$ && elementList$.length>0"
Run Code Online (Sandbox Code Playgroud)

其中 elementList$ 是从服务调用返回的 Observable。

   public elementList$: Observable<Array<Element>>;   

   elementList$ =this.service.getElementList()
Run Code Online (Sandbox Code Playgroud)

我想知道收到 elementList 后如何创建 FormGroup。首先,我需要创建 FormGroup,然后模板应该调用 *ngIf 来绘制元素。

angular angular-reactive-forms async-pipe

5
推荐指数
2
解决办法
4726
查看次数

角度单元测试 - 反应形式值未更新

我是角度单元测试的新手。测试场景:html中的表单视图值等于组件表单值。电子邮件值由共享值检索并在组件注册表单中使用。我可以使用反应式表单从组件中检索电子邮件值,但是当尝试通过本机元素访问时,它给出了空。下面是component.ts

ngOnit(public serviceEmail) {
    this.assignEmailAvailable();
    this.createRegistration();

    }
assignEmailAvailable() {
 if(service.email){
    this.email = serviceEmail.email;
  }
 }   
createRegistration() {
   this.registerForm = new FormGroup({
       email:new FormControl({value:this.email})
    })
}
Run Code Online (Sandbox Code Playgroud)

在 component.spec.ts 中,我将调用此函数并检查两个值是否相同。组件规格

 beforeEach(() => {
    fixture = TestBed.createComponent(RegisterComponent);
    component = fixture.componentInstance;
    service = TestBed.get(serviceEmail);
  });
it('Registration Form Creation', fakeAsync(() => {
    service.email = "dsf@gmail.com";

    fixture.detectChanges();

    component.assignEmailAvailable();
    component.createRegisterForm();

    fixture.detectChanges();
    fixture.whenStable().then(() => {
    const email = fixture.debugElement.query(By.css('input[id="email"]')).nativeElement;
//The value is empty even after creating the form using the component function
    expect(email.value).toBe(component.emailValue);
    });
//THis returns me the …
Run Code Online (Sandbox Code Playgroud)

unit-testing karma-jasmine angular angular-reactive-forms

5
推荐指数
1
解决办法
9824
查看次数

如何使用 angular8 将对象数组绑定到 formGroup 和 formarray

您好,我使用反应式表单将对象数组绑定到 formArray,但在这里,如果我选择一个部分中的任何一项,然后单击“向右移动/向左移动”,则整个对象已从一个部分移动到另一部分。但该功能工作正常,但我无法检测到 form.valuechanges() 中从一个部分到其他部分所做的更改。任何人都可以帮助我检测更改,以防项目已从一个部分移动到另一部分,在这里我想要更改检测,但功能必须按原样工作,我的意思是整个对象从一个部分移动到另一部分。

提前致谢。

我这里有工作 demo2,我希望我之前发布的 demo1 能够像这个 demo2 一样工作,并且 formarray 工作。 演示2

演示: 演示 1

TS:

 private settingsGroupInfoForm() {
    if (!this.agentDetailsList) {
      // Add
     this.agentGroupViewInfoForm = this.FB.group({
          agentGroupView: this.FB.array(
            this.agentInView.map(x=>(x))
          ),
        })
    } else {
      // Edit
      if (this.agentDetailsList) {

       this.agentGroupViewInfoForm = this.FB.group({
          agentGroupView: this.FB.array(this.agentInView.map(x=>(x))),

      })
      }
      this.agentGroupViewInfoForm.valueChanges.subscribe(data => {
          this.formEdit = true;
          console.log('agentGroupViewInfoForm', this.formEdit)
        })
      }
    }
Run Code Online (Sandbox Code Playgroud)

HTML:

 <div class="card-body overflow-auto py-0" *ngIf="agentGroupViewInfoForm"
            [formGroup]="agentGroupViewInfoForm">
                <ul class="list-group list-group-flush" *ngFor="let child of agentInView"   name="agentInGroup" formArrayName="agentGroupView">
                  <li class="list-group-item {{isInActiveItems(child) ? …
Run Code Online (Sandbox Code Playgroud)

angular angular-reactive-forms

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

Angular - 使用 ngx-mask MatDatepicker 和反应形式输入

我想在表单上添加反应式表单控件,并触发错误:

多个自定义值访问器与具有未指定名称属性的表单控件相匹配

一切都是单独工作的,反应式表单验证,掩码或 matDatepicker,任何组合也可以工作,但三者一起提示错误。

这是我的代码:

在组件.ts中

formGroup = new FormGroup({
    date: new FormControl()
  });
Run Code Online (Sandbox Code Playgroud)

在组件.html中

    <mat-form-field>
      <input type="text" matInput [matDatepicker]="date_picker" mask="d0/M0/0000" formControlName="date">
      <mat-datepicker-toggle matSuffix [for]="date_picker"></mat-datepicker-toggle>
      <mat-datepicker #date_picker></mat-datepicker>
    </mat-form-field>
Run Code Online (Sandbox Code Playgroud)

我在用着:

"@angular/cli": "8.3.19"
"ngx-mask": "8.1.7"
"@angular/material": "8.2.3"
Run Code Online (Sandbox Code Playgroud)

angular-material angular angular-reactive-forms ngx-mask mat-datepicker

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