角材料自动完成和API对象

时间:2020-09-30 17:46:24

标签: angular autocomplete angular-material angular9

我与Material的Autocomplete战斗了几天。我从这里开始使用了大量示例,但仍然无法正常工作。 我要实现的是从API获取用户,将其加载为自动完成,因为名称应可见,但我希望将值作为对象。 这是我到目前为止所掌握的:

***API Service:***

export class UserService {
  constructor(private httpClient: HttpClient) {}

  getData() {
    return this.httpClient.get<any>('https://jsonplaceholder.typicode.com/users');
  }
}

***component.ts***

constructor(private usc: BreweryService, private formBuilder: FormBuilder) { 
    this.users = this.usc.getData();
    
  }
  
  ngOnInit() {
    this.form = this.formBuilder.group({
      myControl: ['', Validators.required],
      name: ['', Validators.required]
    });
 
    this.filteredUsers = this.form.controls['myControl'].valueChanges.pipe(
      startWith(''),
      debounceTime(200),
      distinctUntilChanged(),
      switchMap(val => {
        return this.filter(val || '')
        
      })
    )    
}

filter(val: string) {
  return this.users.pipe(
    map(response => response.filter(option => {
      return option.name.toLowerCase().indexOf(val.toLowerCase()) === 0
    }))
  )
}

displayFn(user): string {
  return user.name;
}

***html***
<mat-form-field class="example-full-width">
  <mat-label>Assignee</mat-label>
  <input type="text" matInput formControlName="myControl" [matAutocomplete]="auto">
  <mat-autocomplete #auto="matAutocomplete" 
  [displayWith]="displayFn">
    <mat-option *ngFor="let user of filteredUsers | async" 
        [value]="user">
      <span>{{ user.name }}</span>
    </mat-option>
  </mat-autocomplete>  
</mat-form-field>

控制台抛出错误:

“错误TypeError:val.toLowerCase不是函数”

和自动完成功能无法输入。

我创建了stackblitz来显示问题

1 个答案:

答案 0 :(得分:0)

您需要这样做

  myControl = new FormControl();

之后

this.filteredUsers = this.myControl.valueChanges.pipe(
  startWith(""),
  map(value => (typeof value === "string" ? value : value.name)),
  map(name => (name ? this.filter(name) : this.users.slice()))
);

检查this.users是否为空,并返回名称为的对象列表

并确保filteredUsers是可观察的

filter(val: string) {
    const filterValue = name.toLowerCase();
    return this.users.filter(
      option => option.name.toLowerCase().indexOf(filterValue) === 0
    );
}

希望有用