在Angular 2+中的ngx-bootstrap Typeahead中绑定一个对象而不是字符串

8

我正在使用这个链接来实现Typeahead。现在我正在使用TypeaheadOptionField来在typeahead中显示名称,但它也将名称字符串绑定到模型中。我想绑定对象而不是字符串。

我的HTML代码:

<input formControlName="item"  class="form-control" [typeahead]="allItemsArray" [typeaheadItemTemplate]="customItemTemplate"
          [typeaheadOptionsLimit]="7" [typeaheadMinLength]="0" [typeaheadOptionField]="name" (typeaheadOnSelect)="onSelectItem($event)">

所有项数组:

[
    {
        name: 'a',
        code: '12'
    },
    {
        name: 'b',
        code: '13'
    }
]

Value bound to form control: 'a'
Required value: {'name': 'a', 'code': '12'}

我尝试的一件事是实现一个事件,将模型值设置为对象,但它没有起作用。


你能否请更详细地解释一下?你想要绑定到一个对象数组吗?如果你需要这样的话,可以使用stringify函数。 - Rahul Singh
我想绑定到对象,但typeaheadOptionField属性不允许我这样做。它将模型与item.name绑定,而item.name是一个字符串。我想将模型与对象绑定。 - Pratik
您可以使用PrimeNg Dropdown https://www.primefaces.org/primeng/#/dropdown - Parth Savadiya
我知道还有其他选择,比如primeNg和ng2-typeahead,但我对这个很感兴趣。 - Pratik
我认为你应该使用{id:string, text:string}。你能给我一个allItemsArray的例子吗? - Pterrat
假设allItemsArray有两个值{name:string, code:string}。 - Pratik
2个回答

1
我现在遇到完全相同的问题。 当Angular表单API与typeahead一起使用时,它使用传递给typeaheadOptionField的键的值。这在我的看来是一个错误,或者至少应该是可配置的。 我现在正在用自定义控件包装输入,并使用Output typeaheadOnSelect,当选择typeahead的选项时调用它。在事件数据中,您可以找到整个对象。但是您必须自己处理控件数据管理。 至少目前,我找不到其他解决方案。 编辑: 这是我的代码(删除了所有抽象内容,不保证它能正常工作):
@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)">

现在它可以按以下方式使用:
    <my-typeahead-control formControlName="item" [items]="allItemsArray" itemLabelKey="name"></my-typeahead-control>

1
以下是我如何解决 Angular 7 和 NGX-Bootstrap 3 的问题的基本步骤。
HTML
<input
  [formControl]="myTypeahead"
  [typeahead]="filteredOpts"
  typeaheadOptionField="value"
  (typeaheadOnSelect)="select($event.item)"/>

类型Script

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;
  }
}

基于 Angular Material 自动完成自定义筛选器示例,链接在这里: https://material.angular.io/components/autocomplete/overview 我的情况略微复杂,因为我在 ngOnInit 中使用 API 调用加载 options,但这不是问题。
还要注意的是,这基本上是在 _filter 中执行 typeahead 的工作,而不是最有效的方法。然而,它让我再次前进了一步。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接