如何使用 lodash _.filter() 过滤 Firestore 集合?

Posted

技术标签:

【中文标题】如何使用 lodash _.filter() 过滤 Firestore 集合?【英文标题】:How can I filter a firestore collection using lodash _.filter()? 【发布时间】:2019-01-22 20:27:37 【问题描述】:

我正在尝试过滤从 firebase firestore 检索到的集合(在 angularfire2 的帮助下)。问题是我没有在过滤列表中得到任何东西。

这是我的代码:

companies.component.ts

import  Component, OnInit  from '@angular/core';
import  AngularFirestore, AngularFirestoreCollection  from 'angularfire2/firestore';
import  Observable, BehaviorSubject, combineLatest  from 'rxjs';
import  Company  from '../../shared/models';
import  ReactiveFormsModule, FormGroup, FormBuilder, Validators  from '@angular/forms';
import * as _ from 'lodash';

import  Subject  from 'rxjs';

import  switchMap, map from 'rxjs/operators';


@Component(
  selector: 'app-companies',
  templateUrl: './companies.component.html',
  styleUrls: ['./companies.component.scss']
)

export class CompaniesComponent implements OnInit 

  filters = 
  private companiesCollection: AngularFirestoreCollection<Company>;
  companies: any;
  filteredCompanies: any;

  constructor(private readonly afs: AngularFirestore) 
    this.companiesCollection = afs.collection<Company>('companies');
    this.getCompanies().subscribe(() => 
            this.applyFilters();
    );
  

  ngOnInit() 
  

  getCompanies() 
    return this.companies = this.afs.collection<Company>('companies').valueChanges();
  
  /// filter properties that resolve to true
  filterBoolean(property: string, rule: boolean) 
    if (!rule) this.removeFilter(property)
    else 
      this.filters[property] = val => val
      this.applyFilters()
    
  

  private applyFilters() 
     this.filteredCompanies = _.filter(this.companies, _.conforms(this.filters) )
  

companies.component.html

<div class="field">
  <input type="checkbox" (change)="filterBoolean('firstCondition', $event.target.checked)"> True or false 1?
</div>
<div class="field">
  <input type="checkbox" (change)="filterBoolean('secondCondition', $event.target.checked)"> True or false 2?
</div>
<div class="field">
  <input type="checkbox" (change)="filterBoolean('secondCondition', $event.target.checked)"> True or false 3?
</div>


<!-- (WORKING): Displays all the companies names -->
<div *ngFor="let company of companies | async">
  <h6> company.name </h6>
</div>

<!-- (NOT WORKING): Displays all the filtered companies -->
<div *ngFor="let filteredCompany of filteredCompanies">
  <h6> filteredCompany.name </h6>
</div>

我正在使用什么:

Angular 6、angularfire2 (v.5)、lodash (v.4)。

帮助:

我是否以某种方式不匹配数据结构? 任何人都可能对此有解决方案?

我正在关注this tutorial from Jeff Delaney 并尝试在文章中的“选项 1 - 客户端过滤”下适应 firestore 而不是实时数据库。

任何可以使我更接近目标的帮助将不胜感激。

用解决方案编辑:

DeborahK 的回答帮助我解决了这个问题。

在构造函数中改为:

this.getCompanies().subscribe(companies => 
        this.companies = companies; // <== Added this line
        this.applyFilters();
);

而函数getCompanies() 为:

// Now only returns the retrieved collection    
getCompanies() 
        return this.afs.collection<Company('companies').valueChanges();

【问题讨论】:

【参考方案1】:

this.companies 设置在哪里?看起来您正在将它传递给过滤器,但没有在任何地方设置它。

this.filteredCompanies = _.filter(this.companies, _.conforms(this.filters) )

请注意,在上面的代码中,您使用this.companies 作为过滤源。如果未设置,则不会有任何过滤的公司。

应该是这个代码:

this.getCompanies().subscribe(() => 
        this.applyFilters();
);

也许是这个?

this.getCompanies().subscribe(companies => 
        this.companies = companies;
        this.applyFilters();
);

【讨论】:

感谢您的回答!在 getCompanies() 中设置 this.companies。问题不在于显示 this.companies,这是可行的。我正在努力的是能够显示似乎为空的过滤公司。 是的,但是您使用 this.companies 来执行过滤器。如果那时它是空的,那么您的过滤列表也将是空的。请参阅我的更新答案。 好吧,你是英雄!有效!但我不明白为什么。如果您有时间,您想解释一下为什么没有您的解决方案applyFilters() 无法阅读this.companies?我的意思是,如果我设置了this.companies,我在执行getCompanies() 之后应用了过滤器。不过,非常感谢! :) 我没有看到您在代码 sn-p 中的哪个位置设置了它。您能否更新您的问题以包含您现在设置它的代码,我会看看我是否可以解释它为什么不起作用? 您应该能够在代码 sn-p 中向下滚动并看到 getCompanies() 函数。那里有return this.companies = this.afs.collection&lt;Company&gt;('companies').valueChanges(); 行。

以上是关于如何使用 lodash _.filter() 过滤 Firestore 集合?的主要内容,如果未能解决你的问题,请参考以下文章

Lodash _.filter 函数必须只满足 ONE 条件

Lodash 在尝试使用未定义的属性进行过滤时排除项目

如何将 lodash 对象(过滤器对象)动态转换为 jquery listview

11.6_Filter

jQuery与lodash($_)

如何使用时区感知日期过滤模型?