使用angularfire2在ngFor内部使用firebase-src指令失败



我对angular非常陌生,我正在尝试创建一个以firebase为后端的小型angular应用程序。我已经能够从Firestore中检索文档列表并通过组件显示它,但我现在要做的是在迭代Firestore文档列表的ngFor中显示存储在Firebase Storage中的图像。在查看AngularFire2的文档时,我发现firebase-src指令是一个可能的解决方案,但当我试图将其添加到我的组件模板中时,图像没有显示,控制台显示警告

无法绑定到'firebase-src',因为它不是'img'的已知属性。

我确信我做错了什么,可能我错过了什么,但正如我之前所说,我对Angular是一个全新的人,就像一周前开始的那样。

因此,问题是,如何将Firebase Storage中的图像加载到该场景中?或者可能有可能实现吗?

Bellow代码片段:

pets.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from "@angular/common";
import { PetsRoutingModule } from "./pets-routing.module";
import { PetsPageComponent } from './pets-page.component';
import {MatGridListModule} from '@angular/material/grid-list';
import { MatCardModule } from '@angular/material/card';
import { MatButtonModule } from '@angular/material/button'
import { AngularFirestoreModule } from '@angular/fire/firestore';
import { AngularFireStorageModule } from '@angular/fire/storage';
import { FlexLayoutModule } from '@angular/flex-layout'
@NgModule({
imports: [
CommonModule,
PetsRoutingModule,
MatGridListModule,
AngularFirestoreModule,
MatCardModule,
MatButtonModule,
FlexLayoutModule,
AngularFireStorageModule
],
declarations: [       
PetsPageComponent,
]
})
export class PetsModule { }

pets-page.component.ts

import { Component, OnInit } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/firestore';
import { AngularFireStorage } from '@angular/fire/storage';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
export interface Pet{
name:string;
breed:string;
imagepath:string;
birthdate:object;
gender:string;
microchip:string;
sterilized:boolean;
userid:string;
}
@Component({
selector: 'app-pets-page',
templateUrl: './pets-page.component.html',
styleUrls: ['./pets-page.component.scss']
})
export class PetsPageComponent implements OnInit
{
collection: AngularFirestoreCollection<Pet>;
petsList: Observable<Pet[]>;  
constructor(private firestore: AngularFirestore, public storage: AngularFireStorage){
}
calculateAge(birthday) {
var ageDifMs = Date.now() - birthday.toDate();
const oneyear = new Date('01/01/1971');
var ageDate = new Date(ageDifMs);
if(ageDate.getMilliseconds() < oneyear.getMilliseconds())
{
return (ageDate.getMonth()+1) + ' meses';
}
else
{
var yearAge = Math.abs(ageDate.getUTCFullYear() - 1970);
if(yearAge > 1)
{
return yearAge + ' anos';
}
return yearAge + ' ano';
}
}
loadImage(pet){   
this.storage.ref(pet.imagepath).getDownloadURL().subscribe((url) => {
pet.imageUrl = url;
});
}
ngOnInit(): void {
this.collection = this.firestore.collection('pets');
this.petsList = this.collection.snapshotChanges().pipe(
map(actions => actions.map(a => {
const data = a.payload.doc.data() as Pet;        
const id = a.payload.doc.id;
return { id, ...data };
}))
);
}
}

pets-page.component.html

<div class="row">
<div fxLayout="row" fxLayout.xs="column" fxLayoutWrap fxLayoutGap="0.5%" fxLayoutAlign="center start">
<mat-card *ngFor="let item of petsList | async" class="m-1" id="{{item.id}}">
<mat-card-header>
<div mat-card-avatar class="pet-avatar-img"></div>
<mat-card-title>
{{item.name}}
</mat-card-title>
<mat-card-subtitle>
{{item.breed}}
<br />
{{calculateAge(item.birthdate)}}
</mat-card-subtitle>
</mat-card-header>      
<img firebase-src="{{ item.imagepath }}"/>
<mat-card-content>

</mat-card-content>
<mat-card-actions class="text-right">
<button mat-icon-button id={{item.id}}><i class="fa fa-edit"></i></button>
<button mat-icon-button id={{item.id}}><i class="fa fa-trash"></i></button>
</mat-card-actions>
</mat-card>
</div>    
</div>

好的,找到了一个解决方案,但没有使用angularfire指令。我创建了一个纯管道来处理将存储在Firestore文档中的图像路径转换为存储中的下载url。

波纹管的代码和如何使用它:

import { Pipe, PipeTransform } from '@angular/core';
import { AngularFireStorage } from '@angular/fire/storage';
@Pipe({
name: 'storageurl',
pure: true
})
export class StorageUrlPipe implements PipeTransform {  
constructor(private storage: AngularFireStorage){
}
transform(value: string, args?: any): any {
return this.storage.ref(value).getDownloadURL();
}
}

实施:

<img mat-card-image src="{{item.imagepath | storageurl | async}}" class="pet-image"/>

请注意模板中使用的异步管道。这是必要的,因为storageurl管道将返回一个需要解析的可观察项,以便从存储中检索url。

我不知道这是否是一个干净的最佳实践解决方案,我一周前就开始使用angular,但现在看起来不错。

相关内容

最新更新