javascript - 将 Firestore 可观察对象投射到自定义对象
问题描述
我是 angular 和 firestore 的新手,并试图弄清楚如何将从 firebase 接收到的数据直接转换为模型。这里最好的方法是什么?
目前我得到了数据,但看起来它没有被投射到 Blimp 对象中。当我尝试在视图中对其调用 getImageUrl() 时,我收到以下错误消息。
错误类型错误:_v.context.$implicit.getImageUrl 不是函数
所以我的问题是:将这些 observables 转换为正确的本地模型的最佳和最干净的方法是什么?我期待标签默认投射它。
当前代码
自定义模型类
export class Blimp {
created_at: Date;
file_location: string;
id: string;
constructor() {
console.log('OBJ');
}
getImageUrl() {
return "https://*.com" + this.file_location;
}
}
服务等级
import { Injectable } from '@angular/core';
import {Blimp} from '../models/blimp';
import { AngularFirestore } from '@angular/fire/firestore';
import {AngularFireStorage, AngularFireUploadTask} from '@angular/fire/storage';
import {Observable} from 'rxjs';
import {finalize} from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class BlimpService {
blimps: Observable<Blimp[]>;
constructor(private fireStore: AngularFirestore, private fireDisk: AngularFireStorage) { }
getBlimps() {
this.blimps = this.fireStore.collection<Blimp>('blimps').valueChanges();
return this.blimps;
}
}
显示组件
import { Component, OnInit } from '@angular/core';
import {BlimpService} from '../../services/blimp.service';
import {Observable} from 'rxjs';
import {Blimp} from '../../models/blimp';
@Component({
selector: 'app-blimp-viewer',
templateUrl: './blimp-viewer.component.html',
styleUrls: ['./blimp-viewer.component.scss'],
})
export class BlimpViewerComponent implements OnInit {
blimps: Observable<Blimp[]>;
constructor(private blimpService: BlimpService) { }
ngOnInit() {
this.blimps = this.blimpService.getBlimps();
}
}
看法
<ul>
<li *ngFor="let blimp of blimps | async">
{{ blimp | json}}
<img [src]="blimp.getImageUrl()" />
</li>
</ul>
更新#1
将代码更改为
我现在已将您的示例更改为: getBlimps() {
this.blimps = this.fireStore.collection<Blimp>('blimps')
.valueChanges()
pipe(map(b => {
let blimp = new Blimp();
blimp.created_at = b.created_at;
blimp.file_location = b.file_location;
blimp.id = b.id;
return blimp;
}));
return this.blimps;
}
这仍然在视图中抱怨在对象上找不到 getImageUrl()。
# 解决方案
看起来我忘记了一个 . (点)在最后一个代码中
此代码有效:
this.blimps = this.fireStore.collection<Blimp>('blimps')
.valueChanges()
.pipe(map(collection => {
return collection.map(b => {
let blimp = new Blimp();
blimp.created_at = b.created_at;
blimp.file_location = b.file_location;
blimp.id = b.id;
return blimp;
});
}));
return this.blimps;
解决方案
概念 :
您不会将 observable 转换为对象模型。可观察对象是具有生命周期的流。
一个observable向它的订阅者发出值,你需要订阅你的 observable 以便在它发出值时得到通知。您还需要关闭订阅,否则订阅将持续到您的 observable完成导致内存泄漏。
我可以看到您| async
在html 模板中使用,它是由 angular 处理的订阅,在需要时会自动取消订阅。
获取数据:
您需要将收到的数据映射到一个Blimp
对象,您可以使用map operator。
blimps$: Observable<Blimp[]>; // naming convention, suffix your observable with $
blimps$ = this.fireStore.collection<Blimp>('blimps')
.valueChanges()
.pipe(map(collection => {
return collection.map(b => {
let blimp = new Blimp();
blimp.created_at = b.created_at;
blimp.file_location = b.file_location;
blimp.id = b.id;
console.log(blimp);
console.log(b);
return blimp;
});
}));
return this.blimps;
当我们更改blimps
为 时blimps$
,更改您的 html 模板:
*ngFor="let blimp of blimps$ | async"
编辑 :
您可以使用您的类构造函数来初始化您的对象:
export class Blimp {
created_at?: Date;
file_location?: string;
id?: string;
constructor(blimp: Blimp = {}) {
this.created_at = blimp.created_at;
this.file_location = blimp.file_location;
this.id = blimp.id;
}
getImageUrl() {
return `https://*.com${this.file_location}`; // use string interpolation here
}
blimps$ = this.fireStore.collection<Blimp>('blimps')
.valueChanges()
.pipe(map(collection => {
return collection.map(b => new Blimp(b));
}));
推荐阅读
- apache-spark - Spark 的 reduceByKey 是使用恒定数量的内存,还是使用键数量的线性内存?
- javascript - 雪花中的 UDF JavaScript 实现
- python - 使小部件消失在框架中
- javascript - 需要触发验证
- javascript - 将对象推送到数组中,该数组是数组 Mongoose 中对象的字段
- javascript - 如何回调异步/等待功能
- python - 我可以在 OpenCV 中为 Otsu 阈值添加偏差吗?
- jekyll - 不使用 Jekyll 评估的 Liquid 语法
- objective-c - 以编程方式调用按钮操作导致 NSInvalidArgumentException
- syntax - 'static 可以放在结构声明中吗?