带有对象代码和描述的角材料自动完成

Posted

技术标签:

【中文标题】带有对象代码和描述的角材料自动完成【英文标题】:Angular Material Autocomplete with Object Code and Description 【发布时间】:2021-06-21 13:47:13 【问题描述】:

我正在尝试将 Angular Material Autocomplete 与类一起使用。我在滚动下拉列表中显示了描述,并希望在 formValue 中获取的实际值是代码。

由于某种原因一切正常,自动完成功能会在滚动中显示所有描述,但是当我实际选择描述值时,会在文本框中呈现代码。它仍应显示描述,但将 Code 值存储在表单中。这在使用 mat-select 下拉菜单时工作正常,但是转移到自动完成会导致一些问题。

有人知道如何解决这个问题吗?

打字稿:

 readonly dataSource = DataSource;
 dataSourceFilteredOptions: Observable<Array<BaseParentLookupVm>>;

  private _filterDataSource(value: string): Array<BaseParentLookupVm> 
    const filterValue = value?.toLowerCase() ?? '';
    let data = this.dataSource.filter(option => option.description.toLowerCase().includes(filterValue));
    return data;
  

  createDataSourceFilteredOptions() 
    this.dataSourceFilteredOptions = this.processBatchForm.get('dataSourceField').valueChanges
      .pipe(
        startWith(''),
        map(value => this._filterDataSource(value))
      );
   

 public initializeNewBatchForm(): void 
   this.processBatchForm = this.formBuilder.group(
    'dataSourceField': [null, [Validators.required]],
  );
 

HTML:

  <mat-form-field>
    <mat-label>Data Source</mat-label>
    <input 
      type="text"
      placeholder="Select"
      matInput
      formControlName="'dataSourceField'"
      [matAutocomplete]="templateDataSource">  
      <mat-autocomplete 
        #templateDataSource="matAutocomplete"
      >
      <mat-option>Select</mat-option>
      <mat-option 
        *ngFor="let dataSourceItem of dataSourceFilteredOptions | async" 
        [value]="dataSourceItem.code"
      >
        dataSourceItem.description
      </mat-option>
    </mat-autocomplete>
  </mat-form-field>

补充代码:

export interface BaseParentLookupVm 
  displayOrderId?: number;
  code: string;
  description: string;


export const DataSource: Array<BaseParentLookupVm> = [
   
    displayCode: '1', 
    code: '1111', 
    description: '1111 Description'
  ,
   
    displayCode: '2', 
    code: '2222', 
    description: '2222 Description' 
  ,
   
    displayCode: '3', 
    description: '3333 Description' 
  ,
   
    displayCode: '4', 
    description: '4444 Description'
  
];

资源:

这个答案直接从价值映射到描述,所以他们的工作。 Angular Autocomplete Object

尝试使用文本框更新 [DisplayWith],Angular mat-autocomplete : How to display the option name and not the value in the input

这个答案没有显示如何使用文本框,给出另一个问题How to display using [displayWith] in AutoComplete Material2

【问题讨论】:

【参考方案1】:

要使用 displayWith,您必须将代码更改为:

<mat-form-field>
<mat-label>Data Source</mat-label>
<input 
  type="text"
  placeholder="Select"
  matInput
  formControlName="'dataSourceField'"
  [matAutocomplete]="templateDataSource">  
  <mat-autocomplete #templateDataSource="matAutocomplete" [displayWith]="displayFn">
  <mat-option>Select</mat-option>
  <mat-option 
    *ngFor="let dataSourceItem of dataSourceFilteredOptions | async" 
    [value]="dataSourceItem">
    dataSourceItem.description
  </mat-option>
</mat-autocomplete>

TS

myControl = new FormControl();
options = [
    displayOrderId: 1,
    code: "1111",
    description: "1111 Description"
  ,
  
    displayOrderId: 2,
    code: "2222",
    description: "2222 Description"
  ,
  
    displayOrderId: 3,
    code: "3333",
    description: "3333 Description"
  ,
  
    displayOrderId: 4,
    code: "4444",
    description: "4444 Description"
  
];
filteredOptions: Observable < any > ;

ngOnInit() 
  this.filteredOptions = this.myControl.valueChanges.pipe(
    startWith(""),
    map(value => this._filter(value))
  );


private _filter(value: any) 
  let filterValue = '';
  if (typeof value === "string") 
    filterValue = value.toLowerCase();
   else 
    filterValue = value.description.toLowerCase();
  

  return this.options.filter(
    option => option.description.toLowerCase().indexOf(filterValue) === 0
  );


displayFn(value: any) 
  return value ? value.description : undefined;

【讨论】:

嗨,我刚刚有一个问题,如果有两个字符串怎么办?这里将如何区分?代码和描述? if (typeof value === "string") 另外,我希望 [value]="dataSourceItem" 是代码,而不是整个类 虽然很感激,但很接近 也许是这个?这一切似乎有点乱,if (this.dataSource.find(x => x.code === filterData)) dataSourceDescription = this.dataSource.find(x => x.code === filterData)?.description ; else dataSourceDescription = filterData; ,但类似于 ***.com/a/55268844/15435022 如果你想使用 display ,你必须传递整个对象,导致函数取 [value]。

以上是关于带有对象代码和描述的角材料自动完成的主要内容,如果未能解决你的问题,请参考以下文章

如何将 onchange 与自动完成材料 ui 一起使用?

如何在角度材料 2 中使用 mat-chip 和自动完成来保存选定的对象

角2材料2中的预填充垫自动完成

方法在角度材料自动完成中被多次调用

全局关闭材料 matInput 的自动完成功能

自动完成材料 Angular 2 实施错误