Сбой при использовании директивы firebase-sr c внутри ngFor с angularfire2 - PullRequest
1 голос
/ 21 апреля 2020

Я новичок с angular, действительно новый, и я пытаюсь создать небольшое приложение angular с Firebase в качестве бэкэнда. Я смог получить список документов из Firestore и отобразить его через компонент, но сейчас я пытаюсь показать изображение, сохраненное в Firebase Storage, внутри ngFor, который выполняет итерацию списка документов Firestore. Просматривая документацию AngularFire2, я нашел директиву firebase-sr c в качестве возможного решения, но когда я пытаюсь добавить ее в шаблон компонента, изображение не отображается, а на консоли отображается предупреждение

Невозможно связать с 'firebase-sr c', поскольку это не известное свойство 'img'.

Я уверен, что сделал что-то не так и, возможно, я что-то упускаю, но, как я уже говорил, я совершенно новый с Angular, как начал неделю go.

Итак, вопрос, как я могу загрузить образы из Firebase Storage в этот сценарий? или, может быть, это возможно?

Ниже приведены фрагменты кода:

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>

1 Ответ

0 голосов
/ 22 апреля 2020

Хорошо, нашел решение, но не с помощью директивы 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"/>

Обратите внимание на асин * трубу c, используемую в шаблоне. Это необходимо, поскольку канал storageurl будет возвращать наблюдаемую информацию, которую необходимо разрешить для получения URL-адреса из хранилища.

Я не знаю, является ли это чистым и оптимальным решением, я начал с angular в неделю go, но пока выглядит хорошо.

...