Angular 7 Custom Component registerOnChange не является функцией - PullRequest
2 голосов
/ 06 мая 2019

У меня есть пользовательский компонент почтового индекса, который имеет дело с местоположением dto (широта / долгота / город / штат / почтовый индекс).Когда пользователь вводит почтовый индекс, он отправляет и получает всю необходимую информацию и возвращает ее в форму.Форма является реактивной и имеет группу форм, связанную с компонентом почтового индекса (поэтому группа форм имеет широту / долготу / город / штат / почтовый индекс).

Это прекрасно работает, если я НЕ использую пользовательский компонент.

Когда я перемещаю весь код в пользовательский компонент, который я надеюсь использовать в своих формах, я получаю сообщение о том, что registerOnChange не является функцией.

import { HttpClient } from '@angular/common/http';
import {
  Component,
  EventEmitter,
  forwardRef,
  Input,
  Output
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { LocationDto } from '@model/shared/location-dto';
import { environment } from '@env/environment';

@Component({
  selector: 'foobar-zip-code',
  templateUrl: './zip-code.component.html',
  styles: [],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => ZipCodeComponent),
      multi: true
    }
  ]
})
export class ZipCodeComponent implements ControlValueAccessor {
  @Input()
  label: string;
  @Output()
  retrieved: EventEmitter<LocationDto> = new EventEmitter<LocationDto>();

  _location: LocationDto;
  _isDisabled = false;
  emptyLocation: LocationDto = new LocationDto();

  onChange: any = (location: LocationDto) => {};
  onTouched: any = () => {};

  constructor(private http: HttpClient) {
    this._location = new LocationDto();
  }

  get location() {
    return this._location ? this._location : new LocationDto();
  }

  set location(val) {
    this._location = val;
    this.onChange(this._location);
  }

  get isDisabled() {
    return this._isDisabled;
  }

  set isDisabled(val) {
    this._isDisabled = val;
  }

  public writeValue(value: LocationDto) {
    if (value !== undefined) {
      this.location = value;
      if (this.location.zipCode !== '') {
        this.lookupCity();
      }
    } else {
      this.location = new LocationDto();
    }
  }

  // has access to the function that informs the outside world about changes
  public registerOnChange(fn: (location: LocationDto) => void): void {
    this.onChange= fn;
  }

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

  lookupCity() {
    if (this.location.zipCode.length >= 5) {
      const zipCodeUrl = `${environment.resource.utilities}/ZipLookup?zip=${
        this.location.zipCode
      }`;
      this.http.get(zipCodeUrl).subscribe((response: LocationDto) => {
        Object.assign(this.location, response);
        this.onChange(this.location);
        this.retrieved.emit(this.location);
      });
    } else {
      this.retrieved.emit(this.emptyLocation);
    }
  }
}

Форма, которую я представляю, определена:

  fooBarForm= this.fb.group({
    location: this.fb.group({
      zipCode: [''],
      city: [''],
      state: [''],
      latitude: [0.0],
      longitude: [0.0]
    })
  });

и вызывается в шаблоне с помощью:

    <form [formGroup]="fooBarForm" novalidate>
    <foobar-zip-code
        label="Zip:"
        (retrieved)="zipCodeDetailsRetrieved($event)"
        formControlName="location"
      >
    </foobar-zip-code>
</form>

Компонент почтового индекса находится вSharedModule, который экспортирует компонент (а также CommonModule и ReactiveFormsModule).FooBarModule импортирует SharedModule.Поскольку я не получаю никаких ссылочных ошибок для самого компонента, я предполагаю, что экспорт / импорт настроен правильно.

Опять же, я получаю ошибку «TypeError: control.registerOnChange не является функцией».Я ходил кругами по этому вопросу в течение нескольких дней, поэтому любая помощь или идеи были бы невероятно полезными.Спасибо!

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