Angular의 사용자 지정 컨트롤 구성 요소에서 내부 컨트롤을 터치하는 방법은 무엇입니까?

플라톤 로브

고유 한 사용자 지정 컨트롤 구성 요소가있는 양식이 있습니다.

@Component({
  selector: "my-app",
  template: `
    <form [formGroup]="form">
      <app-custom-control formControlName="customControl"></app-custom-control>
    </form>

    <button (click)="touch()">
      Touch!
    </button>
  `,
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  form: FormGroup;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.form = this.fb.group({
      customControl: "1"
    });
  }

  touch() {
    this.form.markAllAsTouched();
  }
}

내 사용자 지정 컨트롤 구성 요소에는 내부에 또 다른 사용자 지정 컨트롤 구성 요소가 있습니다 (실제 앱에서는 외부 컨트롤 구성 요소에 읽기 및 편집의 두 가지 모드가 있기 때문에 필요합니다).

@Component({
  selector: "app-custom-control",
  template: `
    <ng-select [ngModel]="value" [items]="items"></ng-select>
  `,
  styleUrls: ["./custom-control.component.css"],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: CustomControlComponent,
      multi: true
    }
  ]
})
export class CustomControlComponent implements ControlValueAccessor, OnInit {
  items = ["1", "2"];

  value = null;
  onChange = (value: any) => {};
  onTouched = () => {};

  constructor() {}

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

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

  writeValue(outsideValue: number) {
    this.value = outsideValue;
  }
}

그것은 추가 가능 NG_VALIDATORS으로 CustomControlComponent하고 구성 요소를 검증하는 방법을 구현 (그냥 겨-선택 오류를 올릴 수있다). 하지만 this.form.markAllAsTouched()폼을 감싸는 구성 요소에서 할 때 내부 구성 요소 (ng-select)를 터치하는 방법을 정말 모르겠습니다 .

ngDoCheck수명주기 방법 에서 조작을 시도했지만 허용되지 않는 솔루션이 너무 많이 실행되는 것 같습니다.

플레이 그라운드 : https://stackblitz.com/edit/angular-ivy-u3kdfj

Yurzui

github에는 몇 가지 관련 문제가 있습니다.

할 수있는 일은 ControlValueAccessor control ( outerControl) 및 내부 NgModel control ( innerControl)에 대해 NgControl을 확보하는 것입니다 .

custom-control.component.ts

export class CustomControlComponent implements ControlValueAccessor, AfterViewInit {
  @ViewChild(NgControl) innerNgControl: NgControl;

  constructor(private inj: Injector) {}

  ...

  ngAfterViewInit() { 
    const outerControl = this.inj.get(NgControl).control;
    ...
  }
}

그런 다음이 트릭을 사용하여 터치 된 상태를 내부 제어로 우회 할 수 있습니다.

const prevMarkAsTouched = outerControl.markAsTouched;
outerControl.markAsTouched = (...args: any) => { 
  this.innerNgControl.control.markAsTouched();
  prevMarkAsTouched.bind(outerControl)(...args);
};

갈래 Stackblitz

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관