【问题标题】:How can I make my Firestore search repeatable?如何使我的 Firestore 搜索可重复?
【发布时间】:2020-03-16 11:57:08
【问题描述】:

背景

我的网站上有搜索功能,它使用“数组包含”向用户显示与搜索查询匹配的所有产品。这通过在 'nav' 组件中输入一个输入来实现,该组件将搜索通过 queryparams 传递到结果组件。

导航:

import { Component } from '@angular/core';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { Observable, of } from 'rxjs';
import { map, shareReplay } from 'rxjs/operators';
import { AngularFireAuth } from '@angular/fire/auth';
import { User } from 'src/app/user/email-login/user.model';
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';
import { switchMap } from 'rxjs/operators';
import { Router, NavigationExtras } from '@angular/router';

@Component({
  selector: 'app-shell',
  templateUrl: './shell.component.html',
  styleUrls: ['./shell.component.scss']
})
export class ShellComponent {

  user$: Observable<User>;
  searchResult;
  userID: string;

  isHandset$: Observable<boolean> = this.breakpointObserver.observe([Breakpoints.Handset])
    .pipe(
      map(result => result.matches),
      shareReplay()
    );

  constructor(private breakpointObserver: BreakpointObserver, public afAuth: AngularFireAuth, private db: AngularFirestore, private router: Router) {
    this.user$ = this.afAuth.authState.pipe(
      switchMap(user => {
        if (user) {
          console.log('I just logged someone in!')
          return this.db.doc<User>('users/${user.uid}').valueChanges();
        }
        else{
          return of (null);
        }
      })
    )
  }

  search(event: any){
    var searchQuery;
    searchQuery = event.target.value;
    console.log('routing');
    let userSearch: NavigationExtras = {
      queryParams: {
        searchValue: searchQuery
      }
    }
    this.router.navigate(['search-results'], userSearch);
  }
}

搜索结果:

import { Component, OnInit, Input, SimpleChanges, OnChanges } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { AngularFirestore } from '@angular/fire/firestore';

@Component({
  selector: 'app-search-results',
  templateUrl: './search-results.component.html',
  styleUrls: ['./search-results.component.scss']
})
export class SearchResultsComponent implements OnInit, OnChanges {

  searchQuery: string;
  searchResults;
  collectionRef;

  constructor(private route: ActivatedRoute, private db: AngularFirestore) {
    console.log('being loaded..');
    this.route.queryParams.subscribe(search =>{
      this.searchQuery = search.searchValue;
    });
  }

  ngOnInit() {
    this.searchResults = this.db.collection('products', ref => ref.where('keywords', 'array-contains', this.searchQuery)).valueChanges();
  }

  ngOnChanges(changes: SimpleChanges){ // You need to update here the searchQuery
    this.route.queryParams.subscribe(search =>{
      this.searchQuery = search.searchValue;
      this.searchResults = this.db.collection('products', ref => 
    ref.where('keywords', 'array-contains', this.searchQuery)).valueChanges();
  });

  console.log(changes);
}

}

问题

从搜索结果页面以外的页面执行搜索时,搜索会按预期工作,但是,如果用户进行搜索、被路由到结果页面并进行另一次搜索,则不会得到结果更新为“搜索结果”不再被触发(尽管导航中的搜索功能被触发'。

如何修改我的解决方案以允许用户在第一次搜索之后进行另一次搜索?我确定我遗漏了一些明显的东西,但我不确定是什么。

工作示例:https://padder-939bc.firebaseapp.com/

可用于测试的搜索条件:“黑色”、“蓝色”、“白色”

【问题讨论】:

  • 您要更新搜索结果吗?我没有正确理解您要说的是什么,要搜索您单击按钮的结果,或者您希望在输入搜索的同时更新页面?
  • 嗨@NibrassH - 当用户在输入搜索后按下“输入”时启动搜索,这样做会触发上述问题中的“搜索”功能。
  • @NibrasH 我已经用网站链接更新了问题 - “蓝色”、“黑色”和“白色”都是可以搜索的关键字。如果我搜索“蓝色”,它会向我显示结果,但是,如果我随后停留在结果页面上并在搜索中输入“黑色”,那么尽管触发了搜索功能,结果也不会改变。

标签: javascript angular google-cloud-firestore angularfire2


【解决方案1】:

您无法更新搜索结果的数据,因为您正在调用一次的构造函数中初始化 searchQuery。

您必须在名为 ngOnChanges 的 Angular 函数中更新 searchQuery,如下所示:

搜索结果:

constructor(private route: ActivatedRoute, private db: AngularFirestore) {
    console.log('being loaded..');
    this.route.queryParams.subscribe(search =>{
        this.searchQuery = search.searchValue;
    });
}

ngOnInit() {
    this.searchResults = this.db.collection('products', ref => 
      ref.where('keywords', 'array-contains', this.searchQuery)).valueChanges();
}

ngOnChanges(changes: SimpleChanges){ // You need to update here the searchQuery

      this.route.queryParams.subscribe(search =>{
        this.searchQuery = search.searchValue;
        this.searchResults = this.db.collection('products', ref => 
      ref.where('keywords', 'array-contains', this.searchQuery)).valueChanges();
    });
 }

让我知道它是否有效。

【讨论】:

  • 能否请您在函数 ngOnChanges 中使用 console.log(changes) 并分享输出?
  • 似乎没有触发 ngOnChanges。我已经添加了 console.log,但没有任何输出
  • 请按如下方式导入库:import { onChanges } from '@angular/core'。并将 onChanges 接口添加到您的类中:“Class Myclass implements OnChanges”
  • 嗯,我已经这样做了 - 似乎“搜索结果”页面没有重新加载,所以我不确定这是否是我的路由问题?跨度>
  • 上面提到的“导航”是链接网站上的导航栏组件。它始终存在于整个网站上。 “搜索结果”是在搜索后加载的页面组件,并有效地加载到导航栏下方。唯一的其他代码(除上述之外)是 HTML
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-14
  • 1970-01-01
相关资源
最近更新 更多