在ngFor中使用ngfire2的firebase-src指令失败。

问题描述 投票:1回答:1

我是一个新的angular,真的很新,我试图创建一个以firebase为后台的小型angular app.我已经能够从Firestore中检索一个文档列表,并通过一个组件来显示它,但我现在要做的是在迭代Firestore文档列表的ngFor里面显示一个存储到Firebase存储中的图片。 在查找AngularFire2的文档时,我发现firebase-src指令是一个可能的解决方案,但是当我试图将它添加到我的组件模板中时,图像没有显示出来,控制台显示了一个警告。

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

我肯定我做错了什么,可能我漏掉了什么,但正如我之前所说,我是一个完全陌生的Angular,就像一个星期前开始的。

所以,问题是,我怎么能把Firebase存储的图片加载到这个场景中呢,或者说,也许有可能实现?

下面是代码片段。

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>
angular firebase firebase-storage angularfire2
1个回答
0
投票

好吧,找到了一个解决方案,但不是用angularfire指令,我已经创建了一个纯管道来处理存储在Firestore文档中的图片路径转换为存储的下载网址。

下面是这个管道的代码以及如何使用它。

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"/>

注意模板中使用的async管道,这是必要的,因为sorageurl管道会返回一个observable,需要通过解析才能从存储中获取url。

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

© www.soinside.com 2019 - 2024. All rights reserved.