Angular 6+自定义组件选择

时间:2018-09-02 12:59:02

标签: angular

我不确定这里哪里出了问题。我试图制作一个自定义组件,该控件是<select>控件,用户可以在其中选择一种语言。

当控件呈现时,出现以下错误:

  

TypeError:undefined不是对象(正在评估   'this.valueAccessor.registerOnChange')

组件HTML

<select class="custom-select"
        [id]="id">
  <option *ngFor="let language of languages"
          [ngValue]="language">{{ language.name }}</option>
</select>

组件TS

import { AfterViewInit, Component, forwardRef, Input, OnChanges, SimpleChanges, ViewChild } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, SelectControlValueAccessor } from '@angular/forms';
import { Observable } from 'rxjs';


@Component({
  selector: 'app-select-language',
  templateUrl: 'select-language.component.html',
  styleUrls: ['./select-language.component.scss'],
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => SelectLanguageComponent),
    multi: true
  }]
})
export class SelectLanguageComponent implements ControlValueAccessor, AfterViewInit, OnChanges {

  @ViewChild(SelectControlValueAccessor) private valueAccessor: SelectControlValueAccessor;

  languages: any;

  private formControlChanged: any;
  private formControlTouched: any;

  @Input() id: string;

  constructor() {
    this.languages = [{
      code: 'eng',
      name: 'English'
    }, {
      code: 'dan',
      name: 'Danish'
    }, {
      code: 'fin',
      name: 'Finnish'
    }, {
      code: 'swe',
      name: 'Swedish'
    }];
  }

  public ngAfterViewInit(): void {
    this.valueAccessor.registerOnChange(this.formControlChanged);
    this.valueAccessor.registerOnTouched(this.formControlTouched);
  }

  public ngOnChanges(changes: SimpleChanges): void {
    console.warn('ngOnChanges', changes);
    console.warn('valueAccessor', this.valueAccessor);
  }

  public registerOnChange(fn: any): void {
    this.formControlChanged = fn;
    console.warn('registerOnChange', fn);
  }

  public registerOnTouched(fn: any): void {
    this.formControlTouched = fn;
    console.warn('registerOnTouched', fn);
  }

  writeValue(obj: any) {
    this.valueAccessor.writeValue(obj);
    console.warn('writeValue', obj);
  }

  setDisabledState(isDisabled: boolean) {
    this.valueAccessor.setDisabledState(isDisabled);
    console.warn('setDisabledState', isDisabled);
  }
}

父母标记

<div [formGroup]="form">
  <div class="row">
    <div class="col-lg-6 col-12 form-section-break">
      <div class="form-group">
        <label for="guaranteeDocLanguage">Guarantee document language</label>
        <app-select-language id="guaranteeDocLanguage"
                             controlName="guaranteeDocLanguage"></app-select-language>
      </div>
    </div>
  </div>
</div>

当选择其他FormGroup并尝试实现FormControl时,我似乎无法获得<option> / SelectControlValueAccessor来进行更改未定义的错误。

任何帮助将不胜感激。谢谢。


控制台日志

[Info] [WDS] App updated. Recompiling... (vendor.js, line 102057, x2)
[Info] [WDS] App updated. Reloading... (vendor.js, line 102228)
[Log] Angular is running in the development mode. Call enableProdMode() to enable the production mode. (vendor.js, line 36207)
[Warning] ngOnChanges – {id: SimpleChange} (main.js, line 711)
{id: SimpleChange}Object
[Warning] valueAccessor – undefined (main.js, line 712)
[Warning] valueAccessor – undefined (main.js, line 706)
[Error] ERROR – TypeError: undefined is not an object (evaluating 'this.valueAccessor.registerOnChange')
TypeError: undefined is not an object (evaluating 'this.valueAccessor.registerOnChange')
    error
    View_QuoteStepGuaranteeDetailsComponent_0 (QuoteStepGuaranteeDetailsComponent.ngfactory.js:29)
    logError (vendor.js:44397)
    (anonymous function)
    handleError (vendor.js:34803)
    run (polyfills.js:2455)
    tick (vendor.js:37672)
    (anonymous function) (vendor.js:37557:110)
    onInvoke (vendor.js:36908)
    run (polyfills.js:2455)
    next (vendor.js:37557:85)
    (anonymous function) (vendor.js:36639)
    __tryOrUnsub (vendor.js:83610)
    next (vendor.js:83548)
    _next (vendor.js:83492)
    next (vendor.js:83469)
    next (vendor.js:83235)
    emit (vendor.js:36623)
    checkStable (vendor.js:36877)
    onLeave (vendor.js:36944)
    onInvokeTask (vendor.js:36902)
    runTask (polyfills.js:2505)
    invokeTask (polyfills.js:2813)
    invokeTask (polyfills.js:3857)
    globalZoneAwareCallback (polyfills.js:3883)
[Error] ERROR CONTEXT – DebugContext_ {view: Object, nodeIndex: 11, nodeDef: Object, …}
DebugContext_ {view: Object, nodeIndex: 11, nodeDef: Object, elDef: Object, elView: Object, …}DebugContext_
    error
    View_QuoteStepGuaranteeDetailsComponent_0 (QuoteStepGuaranteeDetailsComponent.ngfactory.js:29)
    logError (vendor.js:44397)
    (anonymous function)
    handleError (vendor.js:34808)
    run (polyfills.js:2455)
    tick (vendor.js:37672)
    (anonymous function) (vendor.js:37557:110)
    onInvoke (vendor.js:36908)
    run (polyfills.js:2455)
    next (vendor.js:37557:85)
    (anonymous function) (vendor.js:36639)
    __tryOrUnsub (vendor.js:83610)
    next (vendor.js:83548)
    _next (vendor.js:83492)
    next (vendor.js:83469)
    next (vendor.js:83235)
    emit (vendor.js:36623)
    checkStable (vendor.js:36877)
    onLeave (vendor.js:36944)
    onInvokeTask (vendor.js:36902)
    runTask (polyfills.js:2505)
    invokeTask (polyfills.js:2813)
    invokeTask (polyfills.js:3857)
    globalZoneAwareCallback (polyfills.js:3883)

0 个答案:

没有答案