跨多个(路由)组件的 AngularFire2 FirebaseListObservable
AngularFire2 FirebaseListObservable across multiple (routed) components
我正尝试与 Angular2/Firebase/AngularFire 一起为我们的帆船俱乐部建立一个社交平台。第一个模块是允许用户通过几个标准(过滤器)搜索俱乐部成员,最多大约 10 个左右。
这本身就意味着我必须四处寻找一种技术来克服 Firebase 中查询功能的缺乏。
我创建了一个组件来管理过滤器,使用 child 路由组件来保存成功过滤成员的列表,然后最终是一个点击处理程序,然后路由到成员个人资料本身。
过滤器组件是这样的:
HTML 模板包含多个用于所有过滤器选择的无线电,例如:性别。单击时,将触发 onFilter 方法。
过滤器组件
<div class="radio">
<label>
<input type="radio" name="genderRadios" id="genderRadioM" value="genderMale" (click)="onFilter('crewGender', 'M')">
Male
</label>
</div>
这就是onFilter方法
constructor(private crewService: CrewService) {}
onFilter(myType, myParam) {
this.crewFilter = this.crewService.updateFilter(myType, myParam);
}
调用 'crewService' 服务以使用新值更新过滤器数组。
这是处理此问题的 crewService 的摘录。
Firebase 服务处理程序 (CrewService)
updateFilter(myType, myParam){
this.crewFilter[myType] = myParam;
return this.crewFilter;
}
您可以看到 crewFilter 数组仅包含所有过滤器的 key:value 对列表。然后 CrewService 服务实现一个方法,该方法获取过滤器数组并将其用作针对我调用的 AngularFire 列表的过滤器,并最终将其生成为 FireBaseListObservable。
@Injectable()
export class CrewService {
private crewFilter:any[] = [];
crews:FirebaseListObservable<any[]>;
constructor(private af: AngularFire) {}
getCrews() {
this.crews = this.af.database.list('/crew').map(items => {
const filtered = items.filter(item => {
let match:boolean = true;
for (let i in this.crewFilter) {
if(this.crewFilter[i] !== 'A') {
if (item[i] !== this.crewFilter[i]) match = false;
}
}
return match;
});
return filtered;
}) as FirebaseListObservable<any[]>;
到目前为止。超好的。这根据所有过滤器(忽略 A)成功过滤了 Firebase 列表。然后在组件模板中,它显示列表,我使用标准的 ngFor 循环来解析它们。
列表组件
<div *ngFor="let crew of crews | async; let i = index" class="crewsummary row">
此 ts 文件包含:
constructor(private crewService: CrewService) { }
ngOnInit() {
this.crews = this.crewService.getCrews();
this.crewFilter = this.crewService.getFilter();
}
以便我调用 crewService 来填充本地 'crews' object。
在此组件中,我还创建了取消过滤器的按钮(A 表示全部,因此单击该按钮将过滤器设置为 'A',然后在过滤器中将其忽略):
<a *ngIf="crewFilter['crewGender'] == 'M'" class="btn btn-primary" (click)="onFilter('crewGender', 'A')">gender: <b>Male</b> <i class="fa fa-fw fa-times"></i></a>
<a *ngIf="crewFilter['crewGender'] == 'F'" class="btn btn-primary" (click)="onFilter('crewGender', 'A')">gender: <b>Female</b> <i class="fa fa-fw fa-times"></i></a>
再次与 TS:
onFilter(myType, myParam) {
this.crewFilter = this.crewService.updateFilter(myType, myParam);
this.crews = this.crewService.getCrews();
}
因为成员列表是从该组件生成的,所以当我在列表组件内 运行 onFilter() 时,它会正确刷新列表并得到正确的结果。
这就是乐趣的开始!
当我首先在过滤器组件中应用过滤器时,我可以让服务 re运行 crewService.getCrews() 来应用过滤器,但它不会被填充到列表组件。
我一直没能找到强制列表组件学习 CrewService.getCrews() 方法有 运行 并创建列表的新版本的方法。
许多小时的搜索和尝试与 observables 和订阅等相关的事情都失败了,当我申请时,我无法让列表组件成功 "subscribe" 到工作人员的变化 object过滤器。 (请注意,数据库本身所做的更改已成功传播)
所以我不知道这对任何人是否有意义,是否有一个相当简单的解决方案,或者我是否陷入了困境,需要重新考虑。
感谢任何帮助!!
谢谢
托尼
如果您要为过滤器使用一个可观察对象,您可以编写一个结合了最新数据库列表和最新过滤器的可观察对象。
过滤器有一个初始值,所以你可以使用 BehaviorSubject
,像这样:
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import 'rxjs/add/operator/combineLatest';
@Injectable()
export class CrewService {
private crewFilter:any[] = [];
private crewFilterSubject = new BehaviorSubject(this.crewFilter);
constructor(private af: AngularFire) {
this.crews = this.af.database
.list('/crew')
.combineLatest(this.crewFilterSubject, (items, filter) => {
const filtered = items.filter(item => {
let match:boolean = true;
for (let i in filter) {
if(filter[i] !== 'A') {
if (item[i] !== filter[i]) match = false;
}
}
return match;
});
return filtered;
}) as FirebaseListObservable<any[]>;
}
updateFilter(myType, myParam){
this.crewFilter[myType] = myParam;
this.crewFilterSubject.next(this.crewFilter);
return this.crewFilter;
}
getCrews() {
return this.crews;
}
然后您将只需要一个单一的、组合的可观察对象。所以你可以在构造函数中创建它。
我正尝试与 Angular2/Firebase/AngularFire 一起为我们的帆船俱乐部建立一个社交平台。第一个模块是允许用户通过几个标准(过滤器)搜索俱乐部成员,最多大约 10 个左右。 这本身就意味着我必须四处寻找一种技术来克服 Firebase 中查询功能的缺乏。 我创建了一个组件来管理过滤器,使用 child 路由组件来保存成功过滤成员的列表,然后最终是一个点击处理程序,然后路由到成员个人资料本身。 过滤器组件是这样的: HTML 模板包含多个用于所有过滤器选择的无线电,例如:性别。单击时,将触发 onFilter 方法。
过滤器组件
<div class="radio">
<label>
<input type="radio" name="genderRadios" id="genderRadioM" value="genderMale" (click)="onFilter('crewGender', 'M')">
Male
</label>
</div>
这就是onFilter方法
constructor(private crewService: CrewService) {}
onFilter(myType, myParam) {
this.crewFilter = this.crewService.updateFilter(myType, myParam);
}
调用 'crewService' 服务以使用新值更新过滤器数组。
这是处理此问题的 crewService 的摘录。
Firebase 服务处理程序 (CrewService)
updateFilter(myType, myParam){
this.crewFilter[myType] = myParam;
return this.crewFilter;
}
您可以看到 crewFilter 数组仅包含所有过滤器的 key:value 对列表。然后 CrewService 服务实现一个方法,该方法获取过滤器数组并将其用作针对我调用的 AngularFire 列表的过滤器,并最终将其生成为 FireBaseListObservable。
@Injectable()
export class CrewService {
private crewFilter:any[] = [];
crews:FirebaseListObservable<any[]>;
constructor(private af: AngularFire) {}
getCrews() {
this.crews = this.af.database.list('/crew').map(items => {
const filtered = items.filter(item => {
let match:boolean = true;
for (let i in this.crewFilter) {
if(this.crewFilter[i] !== 'A') {
if (item[i] !== this.crewFilter[i]) match = false;
}
}
return match;
});
return filtered;
}) as FirebaseListObservable<any[]>;
到目前为止。超好的。这根据所有过滤器(忽略 A)成功过滤了 Firebase 列表。然后在组件模板中,它显示列表,我使用标准的 ngFor 循环来解析它们。
列表组件
<div *ngFor="let crew of crews | async; let i = index" class="crewsummary row">
此 ts 文件包含:
constructor(private crewService: CrewService) { }
ngOnInit() {
this.crews = this.crewService.getCrews();
this.crewFilter = this.crewService.getFilter();
}
以便我调用 crewService 来填充本地 'crews' object。
在此组件中,我还创建了取消过滤器的按钮(A 表示全部,因此单击该按钮将过滤器设置为 'A',然后在过滤器中将其忽略):
<a *ngIf="crewFilter['crewGender'] == 'M'" class="btn btn-primary" (click)="onFilter('crewGender', 'A')">gender: <b>Male</b> <i class="fa fa-fw fa-times"></i></a>
<a *ngIf="crewFilter['crewGender'] == 'F'" class="btn btn-primary" (click)="onFilter('crewGender', 'A')">gender: <b>Female</b> <i class="fa fa-fw fa-times"></i></a>
再次与 TS:
onFilter(myType, myParam) {
this.crewFilter = this.crewService.updateFilter(myType, myParam);
this.crews = this.crewService.getCrews();
}
因为成员列表是从该组件生成的,所以当我在列表组件内 运行 onFilter() 时,它会正确刷新列表并得到正确的结果。
这就是乐趣的开始!
当我首先在过滤器组件中应用过滤器时,我可以让服务 re运行 crewService.getCrews() 来应用过滤器,但它不会被填充到列表组件。
我一直没能找到强制列表组件学习 CrewService.getCrews() 方法有 运行 并创建列表的新版本的方法。
许多小时的搜索和尝试与 observables 和订阅等相关的事情都失败了,当我申请时,我无法让列表组件成功 "subscribe" 到工作人员的变化 object过滤器。 (请注意,数据库本身所做的更改已成功传播)
所以我不知道这对任何人是否有意义,是否有一个相当简单的解决方案,或者我是否陷入了困境,需要重新考虑。
感谢任何帮助!!
谢谢
托尼
如果您要为过滤器使用一个可观察对象,您可以编写一个结合了最新数据库列表和最新过滤器的可观察对象。
过滤器有一个初始值,所以你可以使用 BehaviorSubject
,像这样:
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import 'rxjs/add/operator/combineLatest';
@Injectable()
export class CrewService {
private crewFilter:any[] = [];
private crewFilterSubject = new BehaviorSubject(this.crewFilter);
constructor(private af: AngularFire) {
this.crews = this.af.database
.list('/crew')
.combineLatest(this.crewFilterSubject, (items, filter) => {
const filtered = items.filter(item => {
let match:boolean = true;
for (let i in filter) {
if(filter[i] !== 'A') {
if (item[i] !== filter[i]) match = false;
}
}
return match;
});
return filtered;
}) as FirebaseListObservable<any[]>;
}
updateFilter(myType, myParam){
this.crewFilter[myType] = myParam;
this.crewFilterSubject.next(this.crewFilter);
return this.crewFilter;
}
getCrews() {
return this.crews;
}
然后您将只需要一个单一的、组合的可观察对象。所以你可以在构造函数中创建它。