javascript - 如何在 Firebase 实时数据库中过滤并在 Angular 应用中显示特定内容?
问题描述
我正在使用 Angular 和 Firebase 实时数据库。我的数据库中有一组名为“imageDetail”的照片,其中每个项目都有:-category - caption - imageUrl
我正在尝试根据它们的类别过滤我的项目,并在单独的组件中显示结果。我设法在控制台中获得了正确的结果,但我的问题是我无法在我的组件中显示结果。
在这个例子中,我试图在我的收藏中过滤“自然”类别,我尝试了很多不同的方法,但我要么得到我收藏中的所有照片,要么根本没有照片。
这是我的图像服务中的功能:
getImageByCategory(category: string) {
const dbRef = this.firebaseDB.database.ref('imageDetail');
return dbRef.orderByChild("category").equalTo(category).on("child_added", snap => {
console.log(snap.val()); // -> this shows me what I want
});
}
这是我的 Nature 组件,我打算只显示“自然”类别的照片:
import { Component, OnInit } from '@angular/core';
import { ImageService } from '../services/image.service';
@Component({
selector: 'app-nature',
templateUrl: './nature.component.html',
styleUrls: ['./nature.component.css']
})
export class NatureComponent implements OnInit {
naturePhotos: any[];
constructor(private imageService: ImageService) {
this.naturePhotos = [];
}
ngOnInit(): void {
let listaPhoto = this.imageService.getImageByCategory("nature");
listaPhoto.snapshotChanges().subscribe(
list => {
this.naturePhotos = list.map(item => { return item.payload.val() });
});
}
}
我还收到此错误消息“类型'(a:DataSnapshot,b?:字符串)=> any'上不存在属性'snapshotChanges'。”
我不太确定出了什么问题,谁能帮我弄清楚如何分离我收藏中的每个类别并让它们显示在几个不同的组件中?
解决方案
方法on(...)
不返回结果,它返回您提供的回调
https://firebase.google.com/docs/reference/js/firebase.database.Reference#on
您应该创建一个 Observable 来代替发出您的结果:
getImageByCategory(category: string) {
const dbRef = this.firebaseDB.database.ref('imageDetail');
return Observable.create(observer => {
const callback = dbRef.orderByChild("category")
.equalTo(category)
.on('child_added', snap => {
observer.next(snap.val());
}, error => observer.error(error));
// Return a function with teardown logic that run when you unsubscribe
return () => dbRef.off('child_added', callback);
});
}
请注意,我不熟悉 Firebase 数据库,因此这可能不是最好的方法。
在您的组件中,您可以通过多种方式使用它。
使用异步管道(更简单):
@Component({
selector: 'app-root',
template: `
<div class="container" *ngFor="let photo of photos$ | async">
<div class="photo">
<img src="{{photo.imageURL}}" alt="" />
</div>
</div>
`
})
export class AppComponent {
photos$!: Observable<Photo[]>;
constructor(
private imageService: ImageService
) {}
ngOnInit(): void {
this.photos$ = this.imageService.getImageByCategory('nature');
}
}
通过订阅:
@Component({
selector: 'app-root',
template: `
<div class="container" *ngFor="let photo of photos">
<div class="photo">
<img src="{{photo.imageURL}}" alt="" />
</div>
</div>
`
})
export class AppComponent implements OnInit, OnDestroy {
photos: Photo[] = [];
private subscription!: Subscription;
constructor(
private imageService: ImageService
) {}
ngOnInit(): void {
this.subscription = this.photos = this.imageService.getImageByCategory('nature')
.subscribe(photos => this.photos = photos);
// Or you can do: .subscribe(photos => this.photos.push(...photos);
}
ngOnDestroy(): void {
// This is important to prevent memory leak
this.subscription.unsubscribe();
}
}
推荐阅读
- stm32 - I2c 从机 HAL 发送
- python - 为什么即使我的模型没有用户作为主键,我也会收到 userId 重复键错误?
- ios - 如何像 AppStore 应用程序详细信息页面一样为导航栏设置动画?
- c++ - 使用函数调用更改数组的值
- oracle - 如何使用 Oracle PL/SQL 实现以下代码
- c# - 我不能在表中插入除“Id”值之外的任何内容
- riscv - 如何使用尖峰打印寄存器的值?
- ios - Swift Instagram API 用户名未显示在标签上
- symfony - 无法使用 Symfony Messenger 组件连接到 AmazonMQ
- c++ - c ++无法从地图中获取价值