我正在尝试将回调函数传递给我的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);
}
}
答案 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;
}