【问题标题】:Angular Material autocomplete From API来自 API 的 Angular Material 自动完成
【发布时间】:2020-01-11 03:21:37
【问题描述】:

我尝试从 api 使用自动完成,但它不起作用。 它只在没有 api 的情况下工作。

这是我的组件 TS:里面,有一个回调方法与来自 api 的数据(onGetTaxList)

import { Component, OnInit } from '@angular/core';
import { UsersService } from '../../../../core/services/users.service';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';

@Component({
  selector: 'app-create-process-modal',
  templateUrl: './create-process-modal.component.html',
  styleUrls: ['./create-process-modal.component.sass']
})
export class CreateProcessComponent implements OnInit {
  myControl = new FormControl();
  options = [
    { name: 'One' },
    { name: 'Two' },
    { name: 'Tree' },
  ];
  filteredOptions: Observable<any>;


  constructor(private service: UsersService) { }

  ngOnInit() {
    this.service.createNewProcess((data) => this.onGetTaxList(data));
    this.filteredOptions = this.myControl.valueChanges
      .pipe(
        startWith(''),
        map(value => this._filter(value))
      );
  }

  onGetTaxList(data) {
    console.log(data);
  }
  private _filter(value: string) {
    const filterValue = value.toLowerCase();

    return this.options.filter(option => option.name.toLowerCase().includes(filterValue));
  }
}

组件html:

<div class="formContainer">
    <h2 style="text-align: right">New Process</h2>
    <mat-form-field style="text-align: right">
        <input type="text" placeholder="Start Typing..." matInput [formControl]="myControl" [matAutocomplete]="auto">
        <mat-autocomplete #auto="matAutocomplete">
                <mat-option *ngFor="let option of filteredOptions | async" [value]="option.name">
                  {{option.name}}
                </mat-option>
              </mat-autocomplete>
    </mat-form-field>

</div>

在这种状态下,它与对象一起工作

options = [
        { name: 'One' },
        { name: 'Two' },
        { name: 'Tree' },
      ];

现在我想从数据 api 中获得它的工作:

0: {companyName: "ziro", cid: "524023240", partners: Array(4)}
1: {companyName: "plus", cid: "524023240", partners: Array(2)}

我需要自动完成过滤公司名称。 谢谢。

【问题讨论】:

    标签: angular autocomplete angular-material


    【解决方案1】:

    呼叫数据的最佳方式是对所有数据收费,但服务器端的部分数据除外: 通话从第一个字母开始

    组件无异步

    <form class="example-form">
        <mat-form-field class="example-full-width">
          <input type="text" placeholder="Pick one" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto">
          <mat-autocomplete #auto="matAutocomplete">
            <mat-option *ngFor="let option of filteredOptions" [value]="option.name">
              {{option.name}}
            </mat-option>
          </mat-autocomplete>
        </mat-form-field>
      </form>
    

    .ts 文件

    ngOnInit() {
        this.myControl.valueChanges
          .subscribe(value => {
            if(value.length >= 1){
              this.dashboardService.getProductsByName(value).subscribe(response => {
                this.filteredOptions = response;
              });
            }
            else {
              return null;
            }
          })
    }
    

    【讨论】:

      【解决方案2】:

      组件:

        constructor(private service: Service) { 
        this.filteredOptions = this.myControl.valueChanges
              .pipe(
                startWith(''),
                debounceTime(400),
                distinctUntilChanged(),
                switchMap(val => {
                  return this.filter(val || '')
                })       
              );
        }
      
        // filter and return the values
       filter(val: string): Observable<any[]> {
          // call the service which makes the http-request
          return this.service.getData()
           .pipe(
             map(response => response.filter(option => { 
               return option.name.toLowerCase().indexOf(val.toLowerCase()) === 0
             }))
           )
         }  
      }
      

      服务:

      opts = [];
      
      getData() {
        return this.opts.length ?
          of(this.opts) :
          this.http.get<any>('https://jsonplaceholder.typicode.com/users').pipe(tap(data => this.opts = data))
      }
      
      

      要查看完整演示,请查看此链接Stackblitz

      【讨论】:

        【解决方案3】:

        我看不到从 Api 获取数据的尝试,所以首先你应该添加它。然后您尝试按name 过滤,它在您的数据中不存在,您想按companyName 过滤,然后使用它。总而言之,将您的代码更改为:

        this.filteredOptions = this.myControl.valueChanges
          .pipe(
            startWith(''),
            switchMap(value => this._filter(value))
          );
        

        以及过滤和从api获取数据的功能:

        private _filter(value: string) {
          const filterValue = value.toLowerCase();
          // add your service function here
          return this.service.getData().pipe(
            filter(data => !!data),
            map((data) => {
              return data.filter(option => option.companyName.toLowerCase().includes(value))
            })
          )
        }
        

        演示:StackBlitz

        【讨论】:

          【解决方案4】:

          在您的 ngOnInit 上尝试添加:

          ngOnInit() {
             .
             ..
             ...
             this.options = []; //init the options data.
             this.yourService.getAllCompaniesOrSomething.subscribe((all_companies)=>{
                this.options = all_companies.map((company)=>{ 
                                    return {
                                              name:company.companyName
                                    } 
                                });//closing the map function.
             });//closing the subscription.
          }
          

          【讨论】:

            【解决方案5】:

            已解决:

                import { Component, OnInit } from '@angular/core';
                import { UsersService } from '../../../../core/services/users.service';
                import { FormControl } from '@angular/forms';
                import { Observable } from 'rxjs';
                import { map, startWith } from 'rxjs/operators';
                import { MatAutocompleteSelectedEvent } from '@angular/material';
            
                @Component({
                  selector: 'app-create-process-modal',
                  templateUrl: './create-process-modal.component.html',
                  styleUrls: ['./create-process-modal.component.sass']
                })
                export class CreateProcessComponent implements OnInit {
                  myControl = new FormControl();
                  options;
                  filteredOptions: Observable<any>;
            
            
                  constructor(private service: UsersService) { }
            
                  ngOnInit() {
                    this.service.createNewProcess((data) => this.onGetTaxList(data));
                  }
            
                  // Auth Complete
                  onGetTaxList(data) {
                    this.options = data;
                    this.filteredOptions = this.myControl.valueChanges
                      .pipe(
                        startWith(''),
                        map(value => value.length >= 1 ? this._filter(value) : [])
                      );
                  }
                  private _filter(value: string) {
                    const filterValue = value.toLowerCase();
            
                    return this.options.filter(option => option.companyName.toLowerCase().includes(filterValue));
                  }
            }
            

            HTML:

            <div class="formContainer">
                <h2 style="text-align: right">New Process</h2>
                <mat-form-field style="text-align: right">
                    <input type="text" placeholder="Start Typing..." matInput [formControl]="myControl" [matAutocomplete]="auto">
                    <mat-autocomplete #auto="matAutocomplete">
                            <mat-option *ngFor="let option of filteredOptions | async" [value]="option.companyName">
                              {{option.companyName}}
                            </mat-option>
                          </mat-autocomplete>
                </mat-form-field>
            
            </div>
            

            【讨论】:

            • 但再次收到错误消息 - 无法读取 null 的属性“toLowerCase”。任何解决方案..???
            猜你喜欢
            • 2021-01-16
            • 1970-01-01
            • 2016-10-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-10-14
            • 2018-10-19
            • 2018-02-26
            相关资源
            最近更新 更多