Создать пользовательский FormControl с валидаторами - PullRequest
1 голос
/ 11 июня 2019

Я создал компонент (AComponent), который использует дизайн материалов, и я хотел бы использовать его в качестве formControl в моей Реактивной форме (в AppComponent).Я реализовал ControlValueAccessor в этом компоненте (AComponent).

export class AComponent implements ControlValueAccessor {
  fm = new FormControl();

  constructor(private ngControl: NgControl) {
    ngControl.valueAccessor = this;

    this.fm.valueChanges.subscribe(v => {
      this.onChange(v);
    })
  }

  onChange = (_: any) => {}
  onTouched = () => {}

  writeValue(obj: any) {
    this.fm.setValue(obj);
  }
  registerOnChange(fn: any) {
    this.onChange = fn;
  }
  registerOnTouched(fn: any) {
    this.onTouched = fn;
  }

}

Я могу установить Validators.required для этого компонента (в AppComponent)

  ngOnInit() {
    this.formGroup = this.fb.group({
      control: ['', Validators.required],
      controlOne: ['', Validators.required]
    })

    this.formGroup.statusChanges
      .subscribe(console.log);
  }

, и это влияет нався форма.(вы можете увидеть на консоли: недействительно, когда ACompnent недействителен).

Но проблема в том, что я не могу заставить AComponent выглядеть недопустимым (красный ввод) в случае, когда он недопустим.Похоже, что внутренний formControl (в AComponent) не получает Validators.required от AppComponent.

enter image description here

Вопрос : Как я могу элегантно установить AComponent для валидаторов?

DEMO

Ответы [ 3 ]

1 голос
/ 12 июня 2019

ПРИМЕЧАНИЕ когда мы создаем пользовательский элемент управления формы, Angular добавляет ng-invalid ng-touch в наш компонент. Итак, в целом мы меняем внешний вид нашего элемента управления, используя .css

.ng-invalid.ng-touched
{
color:red;
}

Проблема в том, что мы хотим изменить внешний вид ввода матов внутри нашего пользовательского элемента управления формы. Поэтому нам нужно знать, когда недействителен наш контроль.

в этот стек у вас есть свой пользовательский элемент управления формой.

Ключ знает, когда ваш пользовательский элемент управления формы недействителен. Для этого можно ввести ngControl. Необходимо использовать инъекцию, чтобы избежать циклической зависимости. Итак, наш конструктор это как

constructor(public injector: Injector) { }
  ngOnInit() {
    this.ngControl = this.injector.get(NgControl);
    this.fm.valueChanges.subscribe(v => {
      this.onChange(v);
    })
  }

Ну, мы знаем, когда пользовательский элемент управления действителен, тронут, нетронут ...

Мы собираемся определить .css как

.customError,.custom
{
  display:inline-block;
}
.customError .mat-form-field-empty.mat-form-field-label {
    color: red!important;
}
.customError .mat-form-field-underline {
    background-color: red!important;
}

И используйте ViewEncapsulation.None в нашем компоненте. ViewEncapsulation.None не делает .css во всех приложениях. Это объясняется тем, что мы добавляем класс «.customError» перед .mat-form-field-empty.mat-form-field-label и mat-form-field-underline. В остальном ВСЕ наши компоненты для матов имеют ошибку.

@Component({
   selector: 'app-a',
   templateUrl: './a.component.html',
   styleUrls: [ './a.component.css' ],
   encapsulation:ViewEncapsulation.None,
   providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => AComponent),
    multi: true
   }]
})

После этого мы используем [ngClass] для добавления классов

<div class="custom" 
    [ngClass]="{'customError':ngControl.invalid && ngControl.touched}" >

  <mat-form-field 
      [color]="ngControl.invalid && ngControl.touched?'warn':null" >
     <input matInput  placeholder="Some value" [formControl]="fm" (blur)="onTouched()">
  </mat-form-field>
</div>

Обратите внимание, что мы используем свойство [color] в поле mat-form-field, чтобы подчеркивание ряби стало красным, и как мы используем (размытие), чтобы пометить как прикосновение к элементу управления

1 голос
/ 11 июня 2019

вам необходимо предоставить NG_VALIDATORS

https://medium.com/@tarik.nzl/angular-2-custom-form-control-with-validation-json-input-2b4cf9bc2d73

0 голосов
/ 11 июня 2019
providers: [
    {
        provide: NG_VALUE_ACCESSOR,
        useExisting: forwardRef(() => CustomInputComponent),
        multi: true
    },
    {
        provide: NG_VALIDATORS,
        useExisting: forwardRef(() => CustomInputComponent),
        multi: true
    }  
]

Вы также можете установить классы ошибок ng с помощью @ Hostbinding

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...