Форма с пользовательским компонентом не распознает элемент управления - PullRequest
0 голосов
/ 26 апреля 2019

Я использую пользовательский компонент (custom-text), который имеет следующий код

    @Component({
      selector: 'custom-text, [custom-text]',
      templateUrl: './custom-text.template.html',
      styleUrls: ['./custom-text.component.scss']
    })
    export class CustomTextComponent implements OnInit {


      constructor() { }

      ngOnInit() {
      }
    }

Inside the custom-text.template.html

    <mat-form-field>
      <input matInput 
            id="controlid" 
            name="controlname" 
            maxlength="8"
            [(ngModel)]="value">
    </mat-form-field>

Когда я включаю этот элемент управления в форму (управляемую шаблоном) в другом компоненте.

    <form #someForm="ngForm">
        <div custom-text></div>
    </form>

or 

<form #someForm="ngForm">
    <custom-text></custom-text>
</form>

Я не могу получить экземпляр элемента управления с помощью someForm.controls ['controlId']

Что я делаю не так.

Ответы [ 2 ]

0 голосов
/ 26 апреля 2019

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

@Input() control
//And in .html
<mat-form-field>
      <input matInput 
            id="controlid" 
            name="controlname" 
            maxlength="8"
            [formControl]="control">
</mat-form-field>

Вы используете компонент как

<form #someForm="ngForm">
    <div custom-text [control]="someForm.controls['controlId']"></div>
</form>
0 голосов
/ 26 апреля 2019

Я оставляю в stackblitz самый простой пользовательский элемент управления формы, основанный на вводе материала.

Как вы видите, реализует ControlValueAccessor, который имеет функции:

onChange:any; //declare this function to indicate in any time that you change the value
onTouched:any; //declare this function to indicate in any time that your compoment is touched

 writeValue(value: any[]|any): void {
    this.value=value;
  }

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

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

  setDisabledState(isDisabled: boolean): void {
    this.disabled=isDisabled
  }

И такой провайдер, как

   {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => CustomMat),
      multi: true
    }

Если вы хотите выполнить проверку внутри компонента, вам нужно добавить нового поставщика

   {
      provide: NG_VALIDATORS,
      useExisting: forwardRef(() => CustomMat),
      multi: true,
    }

И создать функцию проверки

validate(control: AbstractControl): ValidationErrors | null{
      //your logic here
      return null;
  }

Я использовал еще две функции:

setValue(value: any){
    this.value=value;
    this.onChange(value);

  }
  focusOut()
  {
    this.onTouched()
  }

Для вызова изменения и прикосновения к функциям

...