我使用this链接来实现Typeahead。现在我使用TypeaheadOptionField在typeahead上显示名称,但它也绑定模型中的名称字符串。我想绑定Object而不是字符串。
我的HTML代码:
<input formControlName="item" class="form-control" [typeahead]="allItemsArray" [typeaheadItemTemplate]="customItemTemplate"
[typeaheadOptionsLimit]="7" [typeaheadMinLength]="0" [typeaheadOptionField]="name" (typeaheadOnSelect)="onSelectItem($event)">
allItemsArray:
[
{
name: 'a',
code: '12'
},
{
name: 'b',
code: '13'
}
]
Value bound to form control: 'a'
Required value: {'name': 'a', 'code': '12'}
我尝试过的一件事是实现一个事件,它将模型值设置为对象,但它没有工作。
答案 0 :(得分:1)
我现在遇到完全相同的问题。
当typeahead与Angular Form API一起使用时,它使用为['Foo', 'bar']
<class 'list'>
中传递的键找到的值。这是一个错误或至少它应该是可配置的。
我现在正在做的是使用自定义控件包装输入并使用在选择typeahead选项时调用的Output typeaheadOptionField
。在事件数据中,您可以找到整个对象。但是你必须自己处理控制数据管理。
至少现在,我找不到另一种解决方案。
编辑:
这是我的代码(删除所有抽象,不保证它有效):
typeaheadOnSelect
模板:
@Component({
selector: 'my-typeahead-control',
templateUrl: './my-typeahead-control.html',
providers: [
{provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MyTypeaheadControl), multi: true}
]
})
export class MyTypeaheadControl implements ControlValueAccessor
{
// -- -- -- -- -- -- -- -- -- -- typeahead data -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
@Input()
public items:any[] | Observable<any[]> = [];
@Input()
public itemLabelKey:string;
// -- -- -- -- -- -- -- -- -- -- internal data -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
public selectedItemLabel:string;
// -- -- -- -- -- -- -- -- -- -- interface implementation -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
public writeValue(obj:any):void
{
this.updateSelectedItemLabel(obj);
}
private onChange:Function;
public registerOnChange(fn:any):void
{
this.onChange = fn;
}
private onTouch:Function;
public registerOnTouched(fn:any):void
{
this.onTouch = fn;
}
public setDisabledState(isDisabled:boolean):void
{
// ...
}
// -- -- -- -- -- -- -- -- -- -- control data handling -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
public onSelect(event:TypeaheadMatch):void
{
this.onTouch();
this.onChange(event.item);
this.updateSelectedItemLabel(event.item);
}
private updateSelectedItemLabel(obj:any):void
{
this.selectedItemLabel = (this.itemLabelKey) ? _.get(obj, this.itemLabelKey) : obj;
}
}
现在可以按如下方式使用:
<input [ngModel]="selectedItemLabel"
[typeahead]="items"
[typeaheadOptionField]="itemLabelKey"
[typeaheadMinLength]="0"
[container]="'body'"
(typeaheadOnSelect)="onSelect($event)">
答案 1 :(得分:1)
基本上,这就是我使用Angular 7和NGX-Bootstrap 3解决此问题的方式。
HTML
<input
[formControl]="myTypeahead"
[typeahead]="filteredOpts"
typeaheadOptionField="value"
(typeaheadOnSelect)="select($event.item)"/>
TypeScript
interface Opt {
value: string;
key: string;
}
export class MyComp implements OnInit {
myTypeahead = new FormControl();
options: Opts[];
filteredOpts: Opts[] = [];
selectedOption: Opt;
constructor() {}
ngOnInit() {
this.myTypeahead.valueChanges.pipe(startWith(''))
.subscribe((value) => {
this.filteredOpts = this._filter(value));
}
private _filter(value: string): Opt[] {
return this.options
.filter((opt: Opt) => opt.value.toLowerCase().includes(value.toLowerCase()));
}
select(opt: Opt) {
this.selectedOption = opt;
}
}
基于此处的“角度材料自动完成”自定义过滤器示例:https://material.angular.io/components/autocomplete/overview
我的情况稍微复杂一点,因为我在options
中通过API调用加载了ngOnInit
,但这不是问题。
还要注意,这基本上是在_filter
中进行预输入的工作,并不是最有效的方法。但是,这让我再次前进。