我们可以简单地将 primeNG 的自动完成功能封装在一个实现 ControlValueAccessor 接口的自定义自动完成组件中。
如果dataKey 被定义为@Input,自定义组件将自定义数据绑定,如果没有定义dataKey,则保持primeNG 的默认行为。
在下面的代码中,我只使用了我需要的属性和事件,但它可以应用于所有由 primeNG 的 API 提供的属性和事件。
这是 HTML 代码:
<p-autoComplete (completeMethod)="completeMethod.emit($event)"
(onClear)="onClear.emit($event)"
(onDropdownClick)="onDropdownClick.emit($event)"
(onSelect)="select($event)"
[dataKey]="dataKey"
[delay]="delay"
[disabled]="disabled"
[dropdown]="dropdown"
[emptyMessage]="emptyMessage"
[field]="field"
[forceSelection]="forceSelection"
[maxlength]="maxLength"
[minLength]="minLength"
[multiple]="multiple"
[placeholder]="placeholder"
[readonly]="readonly"
[required]="required"
[styleClass]="styleClass"
[suggestions]="suggestions"
[unique]="unique"
[(ngModel)]="autoCompleteValue">
</p-autoComplete>
这是打字稿代码:
import { Component, EventEmitter, forwardRef, Input, Output } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'mb-auto-complete',
templateUrl: './auto-complete.component.html',
styleUrls: ['./auto-complete.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AutoCompleteComponent),
multi: true
}
]
})
export class AutoCompleteComponent implements ControlValueAccessor {
@Input() dataKey: string = null;
@Input() delay: number = 300;
@Input() disabled: boolean;
@Input() dropdown: boolean = false;
@Input() emptyMessage: string = null;
@Input() field: any = null;
@Input() forceSelection: boolean = null;
@Input() maxLength: number = null;
@Input() minLength: number = 1;
@Input() multiple: boolean = false;
@Input() placeholder: string;
@Input() readonly: boolean = false;
@Input() required: boolean = false;
@Input() styleClass: string = null;
@Input() suggestions: any[] = [];
@Input() unique: boolean = true;
@Output() completeMethod: EventEmitter<any> = new EventEmitter<any>();
@Output() onClear: EventEmitter<any> = new EventEmitter<any>();
@Output() onDropdownClick: EventEmitter<any> = new EventEmitter<any>();
@Output() onSelect: EventEmitter<any> = new EventEmitter<any>();
private onChange = (value: any): void => { /**/ };
private onTouched = (): void => { /**/};
public autoCompleteValue: any;
public registerOnChange(fn: any): void {
this.onChange = fn;
}
public registerOnTouched(fn: any): void {
this.onTouched = fn;
}
public setDisabledState(isDisabled: boolean): void {
this.disabled = isDisabled;
}
public writeValue(value: any): void {
if (this.dataKey?.length > 0) {
this.autoCompleteValue = this.suggestions.filter((item: any) => item[this.dataKey] === value)[0];
} else {
this.autoCompleteValue = value;
}
}
public select(selectedValue: any): void {
const newValue: any = this.dataKey?.length > 0 ? selectedValue[this.dataKey] : selectedValue;
this.onSelect.emit(newValue);
this.onChange(newValue);
}
}
然后您可以使用您的自定义组件,无论您在哪里使用<p-autoComplete ..>,您都可以将其替换为<mb-autoComplete ..>(当然除了在AutoCompleteComponent 的html 中您必须保留<p-autoComplete ..>)。