【问题标题】:Angular 6 Material Autocomplete Error on selectionAngular 6 Material Autocomplete 选择错误
【发布时间】:2019-03-08 06:10:07
【问题描述】:

我是前端开发的新手。我在我的项目中使用 Angular 6,我想实现一个预先输入/自动完成,它将使用服务从后端获取结果。我能够获得入围结果(基于用户在输入框中提供的文本),但是,一旦做出选择,this.docControl.valueChanges 就会再次被调用,从而导致错误。我的组件名为 DocumentSearch,如下:

export class DocumentSearchComponent implements OnInit {
  docControl = new FormControl('');
  searchText: string;
  filteredOptions$: Observable<Document[]>;
  isLoading: boolean;

  @Output() documentSelected = new EventEmitter<Document>();

  constructor(private _documentService: DocumentService) { }

  ngOnInit() {
    this.filteredOptions$ = this.docControl.valueChanges
      .pipe(
        startWith(''),
        debounceTime(400),
        tap((text: string) => { this.isLoading = true; this.searchText = text; }),
        switchMap((text: string) => this.searchText ? this._documentService
          .getAllMatchingDocument(this.searchText.toLowerCase())
          .pipe(
            finalize(() => this.isLoading = false),
          ) : of([])
        )
      )
    ;
  } 

  public myChangeFunc(event, doc: Document) {
    if (event.source.selected) {
      this.documentSelected.emit(doc);
      this.searchText = doc.documentTitle;
    }
  }

  displayFn(doc?: Document): string | undefined {
     return doc ? doc.documentTitle : undefined;
  }

}

Html 模板很简单:

<form class="example-form">
  <mat-form-field class="example-full-width">
    <input type="text" placeholder="Pick one" aria-label="Number" matInput [formControl]="docControl"
           [matAutocomplete]="auto" >
    <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
      <mat-option *ngFor="let doc of filteredOptions$ | async" (onSelectionChange)="myChangeFunc($event, doc)"
              [value]="doc">
        <span>{{doc.documentTitle}}}</span>
        <small> | ID: {{doc.documentID}}</small>
      </mat-option>
    </mat-autocomplete>
  </mat-form-field>
</form>

当从建议中选择其中一个选项时,控制台上会抛出以下错误。 ERROR TypeError: _this.searchText.toLowerCase is not a function。此外,myChangeFuncdoc 中使用空值调用。

感谢任何帮助。显然,在选择时,this.docControl.valueChanges 被触发,对象Document 也被触发,而不是输入框中的文本。我明确地将text 声明为字符串,希望有一个类转换异常之类的东西,但无济于事。

【问题讨论】:

    标签: autocomplete angular-material angular6


    【解决方案1】:

    您似乎正在通过getAllMatchingDocument 方法使用服务器端过滤。

    当输入有效值时,您可以使用以下方法从 API 检索匹配文档列表:

    // component variable to keep documents
    docs: Observable<Document[]>;
    
    // When the value changes, retrieve filtered list from back-end
    this.docControl.valueChanges
      .pipe(startWith(null), debounceTime(400))
      .subscribe(val => {
        // only if the value is a valid string and not a selected doc object
        if (typeof val === 'string') {
          this.isLoading = true;
          // Update docs
          this._documentService
            .getAllMatchingDocument(val === null ? '' : val.toLowerCase())
            .subscribe(
              results => {
                this.docs = results;
                this.isLoading = false;
              },
              error => {
                console.log('Error');
              }
            )
        }
      });
    

    修改 ngFor:

    <form class="example-form">
      <mat-form-field class="example-full-width">
        <input type="text" placeholder="Pick one" aria-label="Number" matInput [formControl]="docControl"
               [matAutocomplete]="auto" >
        <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
          <mat-option *ngFor="let doc of docs" [value]="doc">
            <span>{{doc.documentTitle}}}</span>
            <small> | ID: {{doc.documentID}}</small>
          </mat-option>
        </mat-autocomplete>
      </mat-form-field>
    </form>
    

    【讨论】:

    • 谢谢。很抱歉迟到的回复。我能够在 switchMap 命令中使用蛮力(读取 typeof)来解决问题。此外,在 (onSelectionEvent) 中获取 undefined 的问题是由于使用不正确 - 在组件初始化期间 $event.target.value 而不是 $event。感谢您的麻烦。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-26
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    相关资源
    最近更新 更多