标签: controlvalueaccessor

嵌套 ControlValueAccessor 的角度验证状态未在父级中正确传播,如何实现此验证?

我在 Angular 10 应用程序中遇到问题,在初始化时将 formGroup 的状态传播到其父级。

问题:在组件初始化时,子表单的验证状态未正确传播到多个级别的父级中。

更准确地说,我有 3 个嵌套组件。它们都是表单,并且两个子级都实现 ControlValueAccessor。它们通过“formControlName”属性进行通信。最深的形式初始化错误(必填字段)。父级不会收到有效性状态(它仍然有效)。

这是问题的重现:

https://stackblitz.com/edit/ngx-sub-form-hzo8wj?file=src/app/app.component.ts

我希望“基本表单组”在初始化时无效。“级别 2”的有效性应在“基本表单组”中的“级别 1”然后“级别 1”中传播。

它可能来自正常的角度周期。

我在等待更好的解决方案时发现了一个 hack:

  public ngAfterViewInit(): void {
    this._injector.get(NgControl).control.updateValueAndValidity();
  }
Run Code Online (Sandbox Code Playgroud)

在第一个角度周期后,我们手动重新启动子级对父级的验证。这是级联在所有子组件中的。

我怎样才能避免使用这个黑客?

angular formgroups controlvalueaccessor

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

Angular ERROR in : No provider for NgControl

我正在创建一个实现 ControlValueAccessor 的组件以在反应式表单中使用,它只是一个输入元素的包装器,上面有一些管道。

我已经注入了 NgControl 以检索有效/无效状态并将它们传播到内部输入元素。

当在另一个输入中找到输入值时,它是无效的。

这是 Stackblitz

在 Stackblitz 上工作正常,但是当我进行ng build --prod 时,它会引发错误:

错误:NgControl 没有提供程序(“[ERROR ->])

你看到任何问题吗?

谢谢!

angular angular-reactive-forms controlvalueaccessor

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

当从父组件中的自定义 formControl 继承验证时 <mat-error> 在 ControlValueAccessor 中不起作用

<mat-error>在子 ControlValueAccessor 组件中没有父formControl验证的影响。

<!-- Parent component template -->
<app-unique-name-text-box [formControl]="categoryName"></app-unique-name-text-box>
Run Code Online (Sandbox Code Playgroud)
// Parent Component ts
this.addCategoryForm = fb.group({
      'categoryName': ['', Validators.compose([Validators.required, BlankSpaceValidator.validate])]
});
this.categoryName = this.addCategoryForm.controls['categoryName'];
Run Code Online (Sandbox Code Playgroud)
<!-- Child component template -->
<mat-form-field class="example-full-width">
    <input matInput placeholder="Name" [formControl]="uniqueNameControl" (blur)="onInputBlur()">
    <mat-error *ngIf="errorState">Enter a unique name</mat-error>
</mat-form-field>
Run Code Online (Sandbox Code Playgroud)
// Child component ts
import {Component, OnInit, Optional, Self} from '@angular/core';
import {ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, NgControl} from '@angular/forms';
import {distinctUntilChanged} from "rxjs/operators";

@Component({
  selector: 'app-unique-name-text-box',
  templateUrl: './unique-name-text-box.component.html',
  styleUrls: ['./unique-name-text-box.component.scss']
})
export class UniqueNameTextBoxComponent implements …
Run Code Online (Sandbox Code Playgroud)

angular-material angular controlvalueaccessor

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

ControlValueAccessor ngModel 未更新

这是简单的自定义表单控件

@Component({
  selector: 'app-custom-control',
  template: `
    {{ value }}
    <input [ngModel]="value" (ngModelChange)="onChange($event)">
  `,
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => CustomControlComponent),
    multi: true,
  }]
})
export class CustomControlComponent implements ControlValueAccessor {

  private value: any;

  private onChange: (val) => void;
  private onTouch: () => void;

  writeValue(value: any) {
    this.value = value;
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouch = fn;
  }
}
Run Code Online (Sandbox Code Playgroud)

使用如下:

@Component({
  selector: 'my-app',
  template: `
    <app-custom-control
      [ngModel]="model"
      (ngModelChange)="onChange($event)">
    </app-custom-control>
    <input [ngModel]="model" …
Run Code Online (Sandbox Code Playgroud)

angular2-ngmodel angular angular-forms controlvalueaccessor

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

如何使用 ControlValueAccessor 在 Angular 8 中默认选择 mat-button-toggle

我正在尝试使用 Angulars ControlValueAccessor 创建自定义元素。目标是具有三种状态的开关:真、假和空。默认情况下应选择 Null,我尝试了其他帖子中的一些解决方案,但它们不起作用。
我尝试在 mat-button-toggle-group 中添加“value=null”,并在 null mat-button-toggle 本身中添加“checked”属性。

HTML:

<div class="nullableBoolWrapper" fxLayout="row">
<mat-label class="centred-vertically">{{ label }}</mat-label>
<mat-button-toggle-group class="selection-button"
[disabled]="isDisabled"
[(ngModel)]="selectedValue"
(change)="changed($event)">
    <mat-button-toggle ngDefaultControl value=true>{{ descriptionList[0].description }}</mat-button-toggle>
    <mat-button-toggle ngDefaultControl value=false>{{ descriptionList[1].description }}</mat-button-toggle>
    <mat-button-toggle ngDefaultControl value=null [disabled]="!selectableNull">{{ descriptionList[2].description }}</mat-button-toggle>
</mat-button-toggle-group>
Run Code Online (Sandbox Code Playgroud)

TS:

import { Description } from './../core/models/description';
import { Component, ViewEncapsulation, forwardRef, Input, OnInit } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

export const NULLABLE_BOOL_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => NullableBoolComponent),
  multi: true
}; …
Run Code Online (Sandbox Code Playgroud)

angular-material angular controlvalueaccessor angular8

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

使用 ControlContainer 创建可重用 matInput 组件时,“没有带有名称的表单控件的值访问器”

我按照本指南创建ControlContainer可重用表单,成功创建了可重用表单组,但是当我尝试使用 创建可重用表单元素时matInput,遇到了No value accessor错误。这是my-form-field.ts文件:

import { Component, Input, OnInit } from '@angular/core';
import {
  ControlContainer,
  FormBuilder, FormControl,
  FormGroup,
  FormGroupDirective,
} from '@angular/forms';

@Component({
  selector: 'my-form-field',
  template: `
    <mat-form-field>
      <mat-label>{{label}}</mat-label>
      <input matInput [formControlName]="formControlName">
    </mat-form-field>
  `,
  viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }],
})
export class MyFormFieldComponent implements OnInit {
  @Input() formControlName: string;
  @Input() label: string;
  formGroup: FormGroup;

  constructor(private ctrlContainer: FormGroupDirective, private formBuilder: FormBuilder) {

  }

  ngOnInit(): void {
    this.formGroup = this.ctrlContainer.form; …
Run Code Online (Sandbox Code Playgroud)

code-reuse angular-material angular angular-reactive-forms controlvalueaccessor

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

Angular V11:NullInjectorError:没有 ControlContainer 的提供者

我有一个根据本文制作的自定义输入:medium.com:dont-reinvent-the-wheel

\n

这是我的代码,它处于严格模式 \xe2\x96\xbc

\n
// input.component.ts\n\nimport { Component, Input, ViewChild } from \'@angular/core\';\nimport {\n    ControlContainer,\n    ControlValueAccessor,\n    FormControl,\n    FormControlDirective,\n    NG_VALUE_ACCESSOR\n} from \'@angular/forms\';\nimport {\n    FloatLabelType,\n    MatFormFieldAppearance\n} from \'@angular/material/form-field\';\n\n@Component({\n    selector: \'app-input\',\n    templateUrl: \'./input.component.html\',\n    styleUrls: [\'./input.component.scss\'],\n    providers: [\n        {\n            provide: NG_VALUE_ACCESSOR,\n            useExisting: InputComponent,\n            multi: true\n        }\n    ]\n})\nexport class InputComponent implements ControlValueAccessor {\n    isDisabled!: boolean;\n\n    @Input() isRequired!: boolean;\n\n    @Input() label!: string;\n\n    @Input() placeholder!: string;\n\n    @Input() readonly!: boolean;\n\n    @Input() appearance: MatFormFieldAppearance = \'fill\';\n\n    @Input() floatLabel: FloatLabelType = \'auto\';\n\n    @ViewChild(FormControlDirective, { static: true })\n …
Run Code Online (Sandbox Code Playgroud)

angular angular-reactive-forms controlvalueaccessor angular-controlvalueaccessor

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

嵌套的自定义FormArray组件不与具有FormArrayName的子窗体绑定

我试图使用CVA具有2个嵌套表单。问题是当我将第二个from绑定到formControl时没有用数据初始化。

Stackblitz

在此处输入图片说明

我有主表格

this.requestForm = this.fb.group({
  garageId: 0,
  routes: new FormArray([
    new FormGroup({
      addressPointId: new FormControl,
      municipalityId: new FormControl,
      regionId: new FormControl,
      rvId: new FormControl,
      sequenceNumber: new FormControl,
      settlementId: new FormControl,
      regionName: new FormControl,
      municipalityName: new FormControl,
      settlementName: new FormControl,
      description: new FormControl,
    })
  ]),
  endDateTime: 0,
});
Run Code Online (Sandbox Code Playgroud)

在主要形式的html中,我使用formArrayName将路由绑定到。

 <app-cva-form-array formArrayName="routes"></app-cva-form-array>
Run Code Online (Sandbox Code Playgroud)

组件CVA-FORM-ARRAY具有。

form = new FormArray([
new FormGroup({
  addressPointId: new FormControl,
  municipalityId: new FormControl,
  regionId: new FormControl,
  rvId: new FormControl,
  sequenceNumber: new FormControl,
  settlementId: new FormControl, …
Run Code Online (Sandbox Code Playgroud)

typescript angular angular-reactive-forms controlvalueaccessor

0
推荐指数
1
解决办法
1168
查看次数