[AngularFire] Angular File Uploads to Firebase Storage with Angular control value accessor

來源:互聯網
上載者:User

標籤:contain   att   tps   storage   core   col   write   you   rmi   

The upload class will be used in the service layer. Notice it has a constructor for file attribute, which has a type of File. This will allows us to initialize new uploads with a JavaScript File object. You will see why this is important in the next step.

export class Upload {  $key: string;  file:File;  name:string;  url:string;  progress:number;  createdAt: Date = new Date();  constructor(file:File) {    this.file = file;  }}

 

Then build the upload service, which can inject to component:

import { Injectable } from ‘@angular/core‘;import {Subject} from ‘rxjs/Subject‘;import {MatSnackBar} from ‘@angular/material‘;import * as firebase from ‘firebase‘;import UploadTaskSnapshot = firebase.storage.UploadTaskSnapshot;import {Upload} from ‘./upload‘;@Injectable()export class UploadService {  uploading$ = new Subject<number>();  completed$ = new Subject<Upload>();  constructor(    private snackBar: MatSnackBar  ) {  }  uploadFile(upload: Upload, folder: string) {    // Create a storage ref    const storageRef = firebase.storage().ref();    const uploadTask = storageRef.child(`${folder}/${upload.file.name}`).put(upload.file);    // Upload file    uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED,      (snapshot: UploadTaskSnapshot) => {        upload.progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;        this.uploading$.next(upload.progress);      },      (err) => {        this.snackBar.open(err.message, ‘OK‘, {          duration: 3000,        });      },      () => {        upload.url = uploadTask.snapshot.downloadURL;        upload.name = upload.file.name;        this.completed$.next(upload);        this.uploading$.next(null);      });  }  deleteUpload(name: string, folder: string) {    const storageRef = firebase.storage().ref();    storageRef.child(`${folder}/${name}`).delete();    this.completed$.next();  }}

 

Component:

import {ChangeDetectionStrategy, Component, forwardRef, Input} from ‘@angular/core‘;import {ControlValueAccessor, NG_VALUE_ACCESSOR} from ‘@angular/forms‘;import {UploadService} from ‘../../services/upload.service‘;import {Upload} from ‘../../services/upload‘;import {Observable} from ‘rxjs/Observable‘;export const TYPE_CONTROL_ACCESSOR = {  provide: NG_VALUE_ACCESSOR,  multi: true,  useExisting: forwardRef(() => ImageUploaderComponent)};@Component({  selector: ‘image-uploader‘,  changeDetection: ChangeDetectionStrategy.OnPush,  providers: [TYPE_CONTROL_ACCESSOR],  templateUrl: ‘./image-uploader.component.html‘,  styleUrls: [‘./image-uploader.component.scss‘]})export class ImageUploaderComponent implements ControlValueAccessor {  @Input() img;  private onTouch: Function;  private onModelChange: Function;  private value: string;  file: Upload;  currentUpload: Upload;  progress$: Observable<number>;  constructor(private uploadService: UploadService) {    this.progress$ = this.uploadService.uploading$;    this.uploadService.completed$.subscribe((upload) => {      if (upload) {        this.setSelected(upload.url);        this.currentUpload = upload;      } else {        this.setSelected(‘‘);        this.currentUpload = null;      }    });  }  onChange($event) {    const file = $event.target.files[0];    this.file = new Upload(file);    this.uploadService.uploadFile(this.file, ‘icons‘);  }  writeValue(value: any): void {    this.value = value;  }  registerOnChange(fn: Function): void {    this.onModelChange = fn;  }  registerOnTouched(fn: Function): void {    this.onTouch = fn;  }  setSelected(value: string): void {    this.value = value;    this.onModelChange(value);    this.onTouch();  }  clear() {    if (this.file) {      this.uploadService.deleteUpload(this.file.name, ‘icons‘);      this.setSelected(‘‘);    }  }}

 

Template:

    <div *ngIf="progress$ | async as p">      <mat-progress-bar mode="determinate" [value]="p"></mat-progress-bar>    </div>    <mat-card-subtitle>      Select / upload icon    </mat-card-subtitle>    <mat-card-content fxLayout="column">      <div fxLayout="row" fxLayoutAlign="space-around">        <div          *ngIf="currentUpload"          class="image-container"          fxFlex="30%">          <img [src]="currentUpload?.url || ‘‘" [alt]="currentUpload?.name || ‘‘">        </div>      </div>

 

[AngularFire] Angular File Uploads to Firebase Storage with Angular control value accessor

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.