Как закончить sh angular, наблюдаемый перед проверкой изменений значения? - PullRequest
0 голосов
/ 23 января 2020

Я создаю строку поиска, похожую на Angular Автозаполнение, но я не могу получить свой массив во времени.

import { Component, OnInit } from '@angular/core';
import { IngredientService } from '../ingredients-shared/ingredient-service.service';
import { Ingredient } from '../ingredients-models/ingredient';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import {map, startWith} from 'rxjs/operators';
@Component({
  selector: 'app-list-ingredients',
  templateUrl: './list-ingredients.component.html',
  styleUrls: ['./list-ingredients.component.css']
})
export class ListIngredientsComponent implements OnInit {

  options: string[] = ['Angular', 'React', 'Vue'];

  mylist: Ingredient[];


  myControl = new FormControl();
  filteredOptions: Observable<Ingredient[]>;


  constructor(public ingredientService: IngredientService) { }

    ngOnInit() {

    this.ingredientService.getAllIngredients().subscribe( (ingredients: Ingredient[]) => {
      this.mylist = ingredients
    });

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


  private _filter(value: string): Ingredient[] {

    console.log(value)
    const filterValue = value.toLowerCase();
    return this.mylist.filter(ingredient => ingredient.ingredient_name.toLowerCase().includes(filterValue));
  }

  displayIngredientName(subject: Ingredient){
    return subject ? subject.ingredient_name : undefined
  }

}

Как вы можете видеть, мне нужно заполнить mylist, прежде чем проверять изменения значений в форма и я не могу понять, как закончить sh заранее.

Я пытался использовать async / await, но я не хочу использовать asyn c в ngOnInit. Я также вставил изменения формы в подписку, но, конечно, это происходит только один раз, поэтому это не сработает.

Любой совет? Спасибо

Редактировать: Это HTML:

    <form>
    <mat-form-field>
        <input type="text" matInput [matAutocomplete]="auto" [formControl]="myControl"/> 
        <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayIngredientName">
            <mat-option *ngFor="let ingredient of filteredList$ | async" [value]="ingredient" >
                {{ingredient.ingredient_name}}
            </mat-option>
        </mat-autocomplete>
    </mat-form-field>
</form>

1 Ответ

0 голосов
/ 23 января 2020

Вам необходимо объединить обе наблюдаемые в один поток, так как они зависят друг от друга. Пользователь может начать печатать перед загрузкой данных, а введенные вами значения поиска подхода до загрузки данных будут игнорироваться.

Вы можете добиться этого следующим образом:

const ingredients$ = this.ingredientService.getAllIngredients();
const searchValues$ = this.myControl.valueChanges.pipe(startWith(''), map(val => val.toLowerCase()));
const filteredList$ = combineLatest(ingredients$, searchValues$)
                      .pipe(map(([list, searchVal]) => list.filter(item => item.ingredient_name.toLowerCase().includes(searchVal))));

Тогда просто используйте asyn c труба в вашем шаблоне. И не забудьте OnPu sh обнаружение изменений. Также полезно использовать debounceTime, чтобы ограничить операции поиска при быстрой печати. ​​

...