如何在Angular 6 Firebase中使用占位符图像?

时间:2018-07-16 15:56:55

标签: angular typescript firebase angular6

我可以上传文件并成功上传到Firebase存储。但是,当我将src绑定到下载URL时,出现以下错误:null:1 GET http://localhost:4200/null 404(未找到)

我想要一个占位符图像来消除此错误。我似乎无法将我的字符串分配给Observable类型。您会建议做什么呢?

file-upload.component.ts

从'@ angular / core'导入{Component,OnInit};     从'angularfire2 / storage'导入{AngularFireStorage,AngularFireUploadTask};     从'../../../node_modules/rxjs'导入{Observable,Subject};     从'../../../node_modules/angularfire2/firestore'导入{AngularFirestore};     从'rxjs / operators'导入{finalize};

@Component({
  selector: 'file-upload',
  templateUrl: './file-upload.component.html',
  styleUrls: ['./file-upload.component.css']
})

export class FileUploadComponent {
  task: AngularFireUploadTask;
  percentage: Observable<number>;
  snapshot: Observable<any>;
  downloadURL: Observable<string | null> ;





  constructor(private storage: AngularFireStorage, private db: AngularFirestore) {
    this.downloadURL = 'http://via.placeholder.com/350x150';
   }

  fileUpload(event){

    const file = event.target.files[0];

    const filePath = `test/${new Date().getTime()}_${file.name}`;

    const fileRef = this.storage.ref(filePath);

    const task = this.storage.upload(filePath, file);

    //observe percentage changes
    this.percentage = task.percentageChanges();
    //get notified when the download URL is available
    task.snapshotChanges().pipe(
      finalize(
        () => {
          this.downloadURL = fileRef.getDownloadURL();
        }
      )
    )
    .subscribe();


  }


}

file-upload.component.html

<div class="container">
  <div class="card">
    <div class="card-header">
      Firebase Cloud Storage & Angular 5
    </div>
    <div class="card-body">
      <h5 class="card-title">Select a file for upload:</h5>
      <input type="file" (change)="fileUpload($event)" accept=".png,.jpg" />
    </div>
    <div class="progress">
      <div class="progress-bar progress-bar-striped bg-success" role="progressbar" [style.width]="(percentage | async) + '%'" [attr.aria-valuenow]="(percentage | async)" aria-valuemin="0" aria-valuemax="100"></div>
  </div>
  <img *ngIf="downloadURL != null" [src]="downloadURL | async" />
  </div>
</div> 

2 个答案:

答案 0 :(得分:4)

您可以使用BehaviorSubject,这比每次从字符串创建可观察对象要容易得多。

downloadURL: BehaviorSubject<string>;

在您的建筑中:

construction () {
 this.downloadURL = new BehaviorSubject<string>('http://via.placeholder.com/350x150');
}

准备获取真实图像时:

task.snapshotChanges().pipe(
  finalize(
    () => {
      const dlImage = fileRef.getDownloadURL();
      this.downloadURL.next(dlImage);
    }
  )
)
.subscribe();

以及您的HTML:

<img src="{{downloadURL | async}}" />

编辑-
我不知道他们在上次更新中更改了上传功能。因此我们可以对其进行编辑并使用“哑巴”但可以肯定的方式。忽略答案的第一部分,只需编辑代码即可。
在HTML中:

<img src="{{(downloadURL | async) || placeHolder}}" />

,然后添加新的占位符:

placeHolder:string = 'http://via.placeholder.com/350x150';

因此,它将异步等待从存储中下载URL(这是Observable),直到那时,它只会放置我们提供的自定义placeHolder。

答案 1 :(得分:0)

我的图片上传器位于一个与ngModel productModel绑定的表单中,这使我可以使用ngIf

  <img
    *ngIf="productModel.product_image"
    class="card-img-top"
    src="{{ oshopUrl }}uploads/{{ this.whichProdImg() }}"
    alt="Card image cap"
  />

当我上传图像时,我的函数whichProdImg具有条件,因为我使用相同的形式进行更新,这意味着可能存在图像文件名:

public returnedWhichProdImg = "";
whichProdImg() {
if (this.urlArr[2]) {
    this.returnedWhichProdImg = this.urlArr[2];
  } else {
    this.returnedWhichProdImg = this.productModel.product_image;
  }
  return this.returnedWhichProdImg;
}

在最终用户单击“上传”按钮时调用的onSubmit函数中,我只需要图像的名称,而不是整个路径,因此我使用split可以使用的最后一个元素。数组:

this.urlArr = this.productModel.fileToUpload.split("\\");

希望有帮助