Пользовательский элемент управления формами не работает в angular с помощью ControlValueAccessor

#angular #form-control #controlvalueaccessor

Вопрос:

Я хотел бы создать пользовательский элемент управления формой, поэтому я реализовал ControlValueAccessor в своем угловом компоненте. После создания пользовательского элемента управления я хотел использовать его в группе форм компонента. Теперь проблема в том, что, когда я что-то вводю в элемент управления, он не показывает ничего, что я хотел показать с помощью двухсторонних привязок. Вот код:

Управление Пользовательской Формой

 <input type="tel" id="myPhone" (blur)="onTouched()" (input)="onChange()" [disabled]="disabled" [value]="value">
 

Файл TS:

 import * as $ from 'jquery';
import { Component, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
    selector: 'international-phone-control',
    templateUrl: './international-phone-control.component.html',
    styleUrls: ['./international-phone-control.component.css'],
    providers: [
        {
            provide: NG_VALUE_ACCESSOR,
            useExisting: forwardRef(() => InternationalPhoneControlComponent),
            multi: true
        }
    ]
})
export class InternationalPhoneControlComponent implements ControlValueAccessor {

    value: string;
    onChange: () => void;
    onTouched: () => void;
    disabled: boolean;

    constructor() {
        $(function () {
            var input = document.querySelector("#myPhone");
            (<any>window).intlTelInput(input, {
                initialCountry: "auto",
                geoIpLookup: function (callback: any) {
                    $.get('https://ipinfo.io?token=0454c4d5e06c30', function () { }, "jsonp").always(function (resp) {
                        var countryCode = (resp amp;amp; resp.country) ? resp.country : "us";
                        callback(countryCode);
                    });
                },
                utilsScript: "https://cdn.jsdelivr.net/npm/intl-tel-input@17.0.3/build/js/utils.js"
            });
        });
    }

    writeValue(value: string): void {
        this.value = value ? value : '';
    }

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

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

Компонент формы для использования пользовательского элемента управления

 <form [formGroup]="myForm">
  <h1>Result:</h1>
  <h2>Value: {{myForm.get('phone')?.value}}</h2>
  <h2>Touched: {{myForm.get('phone')?.touched}}</h2>
  <h2>Dirty: {{myForm.get('phone')?.dirty}}</h2>
  <h2>Error: {{myForm.get('phone')?.hasError('required')}}</h2>
  
  <input type="text" formControlName="userName" class="form-control"/> <br/> <br/>

  <international-phone-control formControlName="phone" class="form-control" [(ngModel)]="myNum"></international-phone-control>
  
  <p class="text-danger" *ngIf="myForm.get('phone')?.dirty amp;amp; myForm.get('phone')?.hasError('required')">
    Your phone is required
  </p>
  
</form>
 

Файл TS:

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

@Component({
  selector: 'app-custom-control-test',
  templateUrl: './custom-control-test.component.html',
  styleUrls: ['./custom-control-test.component.css']
})
export class CustomControlTestComponent implements OnInit {
  myForm: FormGroup;
  myNum: string = "";

  constructor() { }

  ngOnInit() {
    this.myForm = new FormGroup({
      userName:new FormControl('Nasir'),
      phone: new FormControl('', Validators.required)
    });
  }

}
 

Здесь двусторонняя привязка для раздела результатов ничего не показывает.

Комментарии:

1. Я не вижу, где вы вызываете (в своем пользовательском компоненте) функцию propagateChange для каждого изменения вашего «ввода», вы можете попробовать: [ngModel]="selectedTelephone" (ngModelChange)="selectedTelephone=$event;propagateChange($event)" (На самом деле я не совсем уверен, что это была отличная идея присоединиться к jQuery и Angular для пользовательского компонента)

2. Я отредактировал примеры. но это тоже не работает.