在Angular 2 中的NGX-Bootstrap打字中绑定对象而不是字符串



我正在使用此链接实现打字机。现在,我正在使用Typeaheadoptionfield在Typeahead上显示名称,但它也绑定了模型中的名称字符串。我想绑定对象而不是字符串。

我的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'}

我尝试的一件事是实现将模型值设置为对象但行不通的事件。

我现在有完全相同的问题。

与Angular形式API一起使用打字机时,它使用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)">

现在可以使用如下:

    <my-typeahead-control formControlName="item" [items]="allItemsArray" itemLabelKey="name"></my-typeahead-control>

这基本上是我在Angular 7和NGX-Bootstrap 3中解决此问题的方式。

html

<input
  [formControl]="myTypeahead"
  [typeahead]="filteredOpts"
  typeaheadOptionField="value"
  (typeaheadOnSelect)="select($event.item)"/>

打字稿

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

基于角度材料自动完成的自定义过滤器示例:

我的情况更为复杂,因为我在ngOnInit中加载了options,但这没问题。

还要注意,这基本上是在_filter中进行打字机的工作,这不是最有效的方法。但是,这使我再次前进。

最新更新