将回调函数传递给chid会给出“错误TypeError:<func>不是函数”

时间:2018-10-26 09:26:10

标签: angular typescript

我正在尝试将回调函数传递给我的app-autocomplete组件。为此,有一个displayFn输入参数:

<app-autocomplete [displayFn]="displayWith" formControlName="starter">
</app-autocomplete>

父组件仅在其中实现

displayWith(item) {
  return item ? item.name : null;
}

app-autocomplete组件本身具有一个mat-autocomplete组件,其中[displayWith]函数由onSelectEvent进行包装:

<mat-autocomplete [displayWith]="onSelectEvent" #autocomplete="matAutocomplete">
</mat-autocomplete>

所有onSelectEvent做/应该做的工作是保存所选选项,然后调用传递的displayFn

onSelectEvent(option) {
  this.selectedOption = option;
  return this.displayFn(option);
}

但是,我得到了

  

ERROR TypeError: this.displayFn is not a function

我不明白为什么。我与this answer有什么不同?

这是相同的错误

onSelectEvent = (option) => {
  this.selectedOption = option;
  return this.displayFn(option);
}

这是整个组件:

@Component({
  selector: 'app-autocomplete',
  styles: [`
  `],
  template: `
  <div class="app-autocomplete">

    <mat-form-field>
      <input #autocompleteInput matInput
             [placeholder]="placeholder" autocomplete="off" [matAutocomplete]="autocomplete"/>
    </mat-form-field>

    <button mat-icon-button type="button" [disabled]="disabled">
      <mat-icon>clear</mat-icon>
    </button>

    <mat-autocomplete #autocomplete="matAutocomplete" [displayWith]="onSelectEvent" autoActiveFirstOption>
      <mat-option *ngFor="let option of filteredOptions$ | async" [value]="option">
        {{option.name}}
      </mat-option>
    </mat-autocomplete>    
  </div>
  `,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => AutocompleteComponent),
      multi: true,
    },
    {
      provide: NG_VALIDATORS,
      useExisting: forwardRef(() => AutocompleteComponent),
      multi: true,
    }]
})
export class AutocompleteComponent implements OnInit, ControlValueAccessor, Validator {

  @ViewChild('autocompleteInput')
  autocompleteInput: ElementRef;

  @Input()
  options = [];

  @Input()
  placeholder;

  @Input()
  displayFn: (value: any) => string;

  disabled;

  selectedOption;
  filteredOptions$;

  _onChangeCallback = (value: any) => {};
  _onTouchedCallback = () => {};


  ngOnInit() {
    this.filteredOptions$ = of(this.options);
  }

  filterOptions(v) {

  }

  writeValue(obj: any): void {
    this.autocompleteInput.nativeElement.value = obj.value;
  }

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

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

  setDisabledState(isDisabled: boolean): void {

  }

  validate(c: AbstractControl): ValidationErrors | any {
    return undefined;
  }

  onSelectEvent = (option) => {
    this.selectedOption = option;
    return this.displayFn(option);
  }

}

3 个答案:

答案 0 :(得分:0)

您所做的与您链接到的问题相同。您正在使用非箭头功能访问int,该功能在this组件的上下文中未定义。

您的mat-autocomplete应该是箭头功能:

onSelectEvent

我已经创建了stackblitz demo。第一个按钮使用非箭头功能,并且失败的方式与您的代码相同。第二个按钮使用箭头功能并正确调用输入功能。

答案 1 :(得分:0)

this.displayFn应该是app-autocomplete组件的EventEmitter。如果onSelectEvent函数写在app-autocomplete内部,则下面的代码将为您工作。

onSelectEvent(option) {
    this.selectedOption = option;
    return this.displayFn.emit(option);
}

答案 2 :(得分:0)

好的,我只是做错了。令人惊讶的是,花了我很长时间才意识到onSelectionChange中还有一个mat-option-但是公平地说,目前有no example。不过是here

所以我通过了onSelectionChange

<mat-option *ngFor="let option of filteredOptions$ | async" [value]="option" (onSelectionChange)="onSelectionChange(option)" >
  {{option.name}}
</mat-option>

其中存储选择:

onSelectionChange(option) {
  this.selectedOption = option;
}

现在我可以将displayFn传递给displayWith

<mat-autocomplete #autocomplete="matAutocomplete" [displayWith]="displayFn" autoActiveFirstOption>
</mat-autocomplete>

它现在可能来自任何地方,不需要引用app-autocomplete组件:

displayWith(option) {
  return option ? option.name : null;
}