将静态数组搜索转换为可观察的搜索

时间:2018-03-28 20:45:10

标签: angular typescript ionic3 angular5 angularfire2

我有一个问题我无法弄清楚..

我有这个功能,它在我的静态数组上工作正常,但现在我想把它变成我在obseravble中的搜索。

这是home.html中的搜索栏:

<ion-searchbar [(ngModel)]="searchKey" [formControl]="searchControl" (ionInput)="onInput($event)" (ionCancel)="onCancel($event)"></ion-searchbar>

这是home.ts:

export class HomePage {

   searchControl: FormControl;
   searching: any = false;
   restaurantsList: Observable<any[]>;

   constructor(){
       this.restaurantsList = this.restaurantService.getRestaurantList();
       this.searchControl = new FormControl();
   }      

   ionViewDidLoad(){
      this.searchControl.valueChanges.debounceTime(700).subscribe(search => {  
         this.searching = false;
         this.setFilteredItems();
     });
    }
    setFilteredItems(){
       this.restaurantService.filterRestaurants(this.searchKey).subscribe(
           foundRestaurant => this.restaurantsList = foundRestaurant
       )

       console.log(this.restaurantService.filterRestaurants(this.searchKey));
     }

     onInput(event) {
        this.searching = true;
     }

这是餐厅服务。:

export class RestaurantService {

  restaurantsRef: AngularFireList<any>;
  restaurantsList: Observable<any[]>;

  constructor(
      public afDb: AngularFireDatabase
  ) {
      this.restaurantsRef = afDb.list('/restaurants');
      this.restaurantsList = this.restaurantsRef.valueChanges();
  }

   getRestaurantList() {
      return this.restaurantsList;
   }

    filterRestaurants(searchKey: string) {
       let key: string = searchKey.toUpperCase();

       return this.restaurantsList.map(
           restaurantsList => restaurantsList.filter(
              restaurant => [
                restaurant.title.toUpperCase(),
                restaurant.address.toUpperCase(),
                restaurant.city.toUpperCase(),
                restaurant.description.toUpperCase()
            ].join(' ').indexOf(key) > -1)
       );
    }
}

但是在setFilteredItems()方法中,ide在this.restaurantList上说: Type boolean is not assignable to type Observable<any[]>

有没有人知道将restaurantList更改为filteredItems的解决方案?

仅供参考我遵循本教程:LINK

3 个答案:

答案 0 :(得分:1)

this.restaurantService.filterRestaurants返回Observable并且您正在订阅其结果,并且在订阅内部方法中您尝试将结果分配给另一个Observable

如果您想订阅可观察的结果并更新一些餐馆,那么您的restaurantsList应该是一个数组:

class HomePage {
   restaurantsList: any[];

所有代码都可以正常工作。

_______________________________________________

或者,如果您想使用新的observable更新您的observable 那么你不应该在订阅方法

中这样做
setFilteredItems(){
    this.restaurantsList = this.restaurantService.filterRestaurants(this.searchKey);
}

然后在html中使用异步管道来订阅这个Observable并呈现它的值列表(这里我也使用json管道进行调试)

{{restaurantsList | async | json}}

答案 1 :(得分:0)

查看filterRestaurants的返回值,它是一个布尔值。您将restaurantsList的属性定义为Observable。您需要将filterRestaurants的结果转换为Observable。

import { Observable } from 'rxjs/Observable';

const filtered: Observable<boolean> = Observable.of( 
    this.restaurantService.filterRestaurants(this.searchKey)
);


filtered.subscribe(...);

答案 2 :(得分:0)

对我来说似乎存在语法错误。这是临时版本,并通过key

进行正确的搜索检查
filterRestaurants(searchKey: string) {
    //below line isn't needed at all.
    //this.restaurantsList.subscribe()
    let key: string = searchKey.toUpperCase();
    //returns Observable
    return this.restaurantsList.map(
       restaurantsList => {
         restaurantsList.filter(
           let result = restaurant => [
              restaurant.title.toUpperCase(),
              restaurant.address.toUpperCase(),
              restaurant.city.toUpperCase(),
              restaurant.description.toUpperCase()
           ].join(' ').indexOf(key) > -1
          );
          return Observable.of(result);
       }
    );
}