prosource

각도: 매트 양식 필드에는 매트 양식 필드 컨트롤이 포함되어야 합니다.

probook 2023. 6. 22. 21:59
반응형

각도: 매트 양식 필드에는 매트 양식 필드 컨트롤이 포함되어야 합니다.

사용자 지정 전화번호 입력 컨트롤이 있는 양식 필드를 추가하려고 합니다.저는 https://material.angular.io/components/form-field/examples 의 전화기의 예를 사용했습니다.

코드는 다음과 같습니다.

<mat-form-field>
  <example-tel-input placeholder="Phone number" required></example-tel-input>
  <mat-icon matSuffix>phone</mat-icon>
  <mat-hint>Include area code</mat-hint>
</mat-form-field>
import {FocusMonitor} from '@angular/cdk/a11y';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {Component, ElementRef, Input, OnDestroy} from '@angular/core';
import {FormBuilder, FormGroup} from '@angular/forms';
import {MatFormFieldControl} from '@angular/material';
import {Subject} from 'rxjs';

/** @title Form field with custom telephone number input control. */
@Component({
  selector: 'form-field-custom-control-example',
  templateUrl: 'form-field-custom-control-example.html',
  styleUrls: ['form-field-custom-control-example.css'],
})
export class FormFieldCustomControlExample {}

/** Data structure for holding telephone number. */
export class MyTel {
  constructor(public area: string, public exchange: string, public subscriber: string) {}
}

/** Custom `MatFormFieldControl` for telephone number input. */
@Component({
  selector: 'example-tel-input',
  templateUrl: 'example-tel-input-example.html',
  styleUrls: ['example-tel-input-example.css'],
  providers: [{provide: MatFormFieldControl, useExisting: MyTelInput}],
  host: {
    '[class.example-floating]': 'shouldLabelFloat',
    '[id]': 'id',
    '[attr.aria-describedby]': 'describedBy',
  }
})
export class MyTelInput implements MatFormFieldControl<MyTel>, OnDestroy {
  static nextId = 0;

  parts: FormGroup;
  stateChanges = new Subject<void>();
  focused = false;
  ngControl = null;
  errorState = false;
  controlType = 'example-tel-input';
  id = `example-tel-input-${MyTelInput.nextId++}`;
  describedBy = '';

  get empty() {
    const {value: {area, exchange, subscriber}} = this.parts;

    return !area && !exchange && !subscriber;
  }

  get shouldLabelFloat() { return this.focused || !this.empty; }

  @Input()
  get placeholder(): string { return this._placeholder; }
  set placeholder(value: string) {
    this._placeholder = value;
    this.stateChanges.next();
  }
  private _placeholder: string;

  @Input()
  get required(): boolean { return this._required; }
  set required(value: boolean) {
    this._required = coerceBooleanProperty(value);
    this.stateChanges.next();
  }
  private _required = false;

  @Input()
  get disabled(): boolean { return this._disabled; }
  set disabled(value: boolean) {
    this._disabled = coerceBooleanProperty(value);
    this.stateChanges.next();
  }
  private _disabled = false;

  @Input()
  get value(): MyTel | null {
    const {value: {area, exchange, subscriber}} = this.parts;
    if (area.length === 3 && exchange.length === 3 && subscriber.length === 4) {
      return new MyTel(area, exchange, subscriber);
    }
    return null;
  }
  set value(tel: MyTel | null) {
    const {area, exchange, subscriber} = tel || new MyTel('', '', '');
    this.parts.setValue({area, exchange, subscriber});
    this.stateChanges.next();
  }

  constructor(fb: FormBuilder, private fm: FocusMonitor, private elRef: ElementRef<HTMLElement>) {
    this.parts = fb.group({
      area: '',
      exchange: '',
      subscriber: '',
    });

    fm.monitor(elRef, true).subscribe(origin => {
      this.focused = !!origin;
      this.stateChanges.next();
    });
  }

  ngOnDestroy() {
    this.stateChanges.complete();
    this.fm.stopMonitoring(this.elRef);
  }

  setDescribedByIds(ids: string[]) {
    this.describedBy = ids.join(' ');
  }

  onContainerClick(event: MouseEvent) {
    if ((event.target as Element).tagName.toLowerCase() != 'input') {
      this.elRef.nativeElement.querySelector('input')!.focus();
    }
  }


  }

example-tel-input-input-message.dll

  <div [formGroup]="parts" class="example-tel-input-container">
      <input class="example-tel-input-element" formControlName="area" size="3">
      <span class="example-tel-input-spacer">&ndash;</span>
      <input class="example-tel-input-element" formControlName="exchange" size="3">
      <span class="example-tel-input-spacer">&ndash;</span>
      <input class="example-tel-input-element" formControlName="subscriber" size="4">
    </div>

그러나 다음 오류가 발생합니다.

오류 오류: mat-form-field는 matFormFieldControl을 포함해야 합니다.

할 필요가 있다import두 개의 모듈과 수입 및 수출 섹션에 있는 모듈을 추가합니다.

import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';

@NgModule ({
  imports: [ MatFormFieldModule, MatInputModule ],
  exports: [ MatFormFieldModule, MatInputModule ]
})

그리고 모두가 가장 그리워하는 것은'/'성격.Angular Material Documentation(각형 재료 설명서)을 보면 이 또한 놓칩니다(Last Checked 2020년 6월 16일, 업데이트 여부조차 알 수 없음).나는 설명을 위해 예시를 만듭니다.

<!-- Wrong -->
<mat-form-field>
  <input matInput>
</mat-form-field>

<!-- Right -->
<mat-form-field>
  <input matInput />
</mat-form-field>

그 토막글을 주의 깊게 보세요.언제<input시작은 다음과 같이 끝나야 합니다./>하지만 대부분의 사람들은 그것을 그리워합니다./(백슬래시) 문자입니다.

매트 입력 모듈을 가져와야 합니다.<mat-form-field>포함하다<input>와 함께matInput / matSelect지시 사항

https://github.com/angular/material2/issues/7898

수입품MatInputModule나의 실수를 해결했습니다.

클래스를 다음에 대한 공급자로 지정해야 합니다.MatFormFieldControl

https://material.angular.io/guide/creating-a-custom-form-field-control#providing-our-component-as-a-matformfieldcontrol

@Component({
  selector: 'form-field-custom-control-example',
  templateUrl: 'form-field-custom-control-example.html',
  styleUrls: ['form-field-custom-control-example.css'],
  providers: [
    { provide: MatFormFieldControl, useExisting: FormFieldCustomControlExample }   
  ]
})

또한 입력 태그에 이름 속성을 기록하는 것을 잊지 마십시오.

name="yourName"
  1. 코드에서 'mat-form-field'와 함께 'input' 태그를 사용하는 경우, 'matInput'을 입력 태그에 포함해야 합니다.

  2. 'mat-form-field'의 하위 태그에 *ngIf가 있는 경우 'mat-form-field' 태그에 *ngIf 조건을 지정합니다.

입력 태그를 닫는 또 다른 문제가 발생할 수 있습니다.Angular 예제(https://material.angular.io/components/datepicker/overview), 중 하나에서 코드를 복사하면 다음 코드가 나타날 수 있습니다.

<mat-form-field appearance="fill">
  <mat-label>Choose a date</mat-label>
  <input matInput [matDatepicker]="picker">
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

입력에는 닫기 태그(슬래시)가 있어야 합니다.

<input matInput [matDatepicker]="picker" />

이것이 당신의 문제를 해결할 것입니다.

 import {
      MatFormFieldModule, 
      MatInputModule
    } from "@angular/material";

오류가 발생했습니다.mat-form-field입력을 가져올 폼 필드를 하나 이상 포함해야 합니다.

예:matInput mat-select기타.

당신의 경우 추가할 수 있습니다.matInputexample-tel-input-input-input.dll 내의 입력 필드에 태그를 지정합니다.그리고 또한 당신은 움직일 수 있습니다.mat-form-field안에서.example-tel-input-example구성 요소 및 각 구성 요소에 대해 추가matInput들판.

<div [formGroup]="parts" class="example-tel-input-container">
      <mat-form-field>
         <input matInput class="example-tel-input-element" formControlName="area" size="3">
      </mat-form-field>
      <span class="example-tel-input-spacer">&ndash;</span>
      <mat-form-field>
          <input matInput class="example-tel-input-element" formControlName="exchange" size="3">
      </mat-form-field>
      <span class="example-tel-input-spacer">&ndash;</span>
      <mat-form-field>
          <input matInput class="example-tel-input-element" formControlName="subscriber" size="4">
      </mat-form-field>
</div>

참고:mat-icon또는mat-hint폼 필드로 간주할 수 없습니다.

언급URL : https://stackoverflow.com/questions/53935928/angular-mat-form-field-must-contain-a-matformfieldcontrol

반응형