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.

  1. export class Upload {
  2. $key: string;
  3. file:File;
  4. name:string;
  5. url:string;
  6. progress:number;
  7. createdAt: Date = new Date();
  8. constructor(file:File) {
  9. this.file = file;
  10. }
  11. }

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

  1. import { Injectable } from '@angular/core';
  2. import {Subject} from 'rxjs/Subject';
  3. import {MatSnackBar} from '@angular/material';
  4.  
  5. import * as firebase from 'firebase';
  6. import UploadTaskSnapshot = firebase.storage.UploadTaskSnapshot;
  7. import {Upload} from './upload';
  8.  
  9. @Injectable()
  10. export class UploadService {
  11.  
  12. uploading$ = new Subject<number>();
  13. completed$ = new Subject<Upload>();
  14.  
  15. constructor(
  16. private snackBar: MatSnackBar
  17. ) {
  18.  
  19. }
  20.  
  21. uploadFile(upload: Upload, folder: string) {
  22.  
  23. // Create a storage ref
  24. const storageRef = firebase.storage().ref();
  25. const uploadTask = storageRef.child(`${folder}/${upload.file.name}`).put(upload.file);
  26. // Upload file
  27. uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED,
  28. (snapshot: UploadTaskSnapshot) => {
  29. upload.progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
  30. this.uploading$.next(upload.progress);
  31. },
  32. (err) => {
  33. this.snackBar.open(err.message, 'OK', {
  34. duration: 3000,
  35. });
  36. },
  37. () => {
  38. upload.url = uploadTask.snapshot.downloadURL;
  39. upload.name = upload.file.name;
  40. this.completed$.next(upload);
  41. this.uploading$.next(null);
  42. });
  43. }
  44.  
  45. deleteUpload(name: string, folder: string) {
  46. const storageRef = firebase.storage().ref();
  47. storageRef.child(`${folder}/${name}`).delete();
  48. this.completed$.next();
  49. }
  50. }

Component:

  1. import {ChangeDetectionStrategy, Component, forwardRef, Input} from '@angular/core';
  2. import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
  3.  
  4. import {UploadService} from '../../services/upload.service';
  5. import {Upload} from '../../services/upload';
  6. import {Observable} from 'rxjs/Observable';
  7.  
  8. export const TYPE_CONTROL_ACCESSOR = {
  9. provide: NG_VALUE_ACCESSOR,
  10. multi: true,
  11. useExisting: forwardRef(() => ImageUploaderComponent)
  12. };
  13.  
  14. @Component({
  15. selector: 'image-uploader',
  16. changeDetection: ChangeDetectionStrategy.OnPush,
  17. providers: [TYPE_CONTROL_ACCESSOR],
  18. templateUrl: './image-uploader.component.html',
  19. styleUrls: ['./image-uploader.component.scss']
  20. })
  21. export class ImageUploaderComponent implements ControlValueAccessor {
  22.  
  23. @Input() img;
  24.  
  25. private onTouch: Function;
  26. private onModelChange: Function;
  27. private value: string;
  28.  
  29. file: Upload;
  30. currentUpload: Upload;
  31. progress$: Observable<number>;
  32.  
  33. constructor(private uploadService: UploadService) {
  34. this.progress$ = this.uploadService.uploading$;
  35. this.uploadService.completed$.subscribe((upload) => {
  36.  
  37. if (upload) {
  38. this.setSelected(upload.url);
  39. this.currentUpload = upload;
  40. } else {
  41. this.setSelected('');
  42. this.currentUpload = null;
  43. }
  44. });
  45. }
  46.  
  47. onChange($event) {
  48. const file = $event.target.files[0];
  49. this.file = new Upload(file);
  50. this.uploadService.uploadFile(this.file, 'icons');
  51. }
  52.  
  53. writeValue(value: any): void {
  54. this.value = value;
  55. }
  56.  
  57. registerOnChange(fn: Function): void {
  58. this.onModelChange = fn;
  59. }
  60.  
  61. registerOnTouched(fn: Function): void {
  62. this.onTouch = fn;
  63. }
  64.  
  65. setSelected(value: string): void {
  66. this.value = value;
  67. this.onModelChange(value);
  68. this.onTouch();
  69. }
  70.  
  71. clear() {
  72. if (this.file) {
  73. this.uploadService.deleteUpload(this.file.name, 'icons');
  74. this.setSelected('');
  75. }
  76. }
  77. }

Template:

  1. <div *ngIf="progress$ | async as p">
  2. <mat-progress-bar mode="determinate" [value]="p"></mat-progress-bar>
  3. </div>
  4. <mat-card-subtitle>
  5. Select / upload icon
  6. </mat-card-subtitle>
  7.  
  8. <mat-card-content fxLayout="column">
  9. <div fxLayout="row" fxLayoutAlign="space-around">
  10. <div
  11. *ngIf="currentUpload"
  12. class="image-container"
  13. fxFlex="30%">
  14. <img [src]="currentUpload?.url || ''" [alt]="currentUpload?.name || ''">
  15. </div>
  16. </div>

[AngularFire] Angular File Uploads to Firebase Storage with Angular control value accessor的更多相关文章

  1. [Angular] Implement a custom form component by using control value accessor

    We have a form component: <label> <h3>Type</h3> <workout-type formControlName=& ...

  2. [转]File uploads in ASP.NET Core

    本文转自:https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads By Steve Smith ASP.NET MVC ...

  3. Asp.net mvc 3 file uploads using the fileapi

    Asp.net mvc 3 file uploads using the fileapi I was recently given the task of adding upload progress ...

  4. The lesser known pitfalls of allowing file uploads on your website

    These days a lot of websites allow users to upload files, but many don’t know about the unknown pitf ...

  5. 从Java角度理解Angular之入门篇:npm, yarn, Angular CLI

    本系列从Java程序员的角度,带大家理解前端Angular框架. 本文重点介绍Angular的开发.编译工具:npm, yarn, Angular CLI,它们就像Java在中的Maven,同时顺便介 ...

  6. (转载)从Java角度理解Angular之入门篇:npm, yarn, Angular CLI

    本系列从Java程序员的角度,带大家理解前端Angular框架. 本文是入门篇.笔者认为亲自动手写代码做实验,是最有效最扎实的学习途径,而搭建开发环境是学习一门新技术最需要先学会的技能,是入门的前提. ...

  7. Angular 个人深究(一)【Angular中的Typescript 装饰器】

    Angular 个人深究[Angular中的Typescript 装饰器] 最近进入一个新的前端项目,为了能够更好地了解Angular框架,想到要研究底层代码. 注:本人前端小白一枚,文章旨在记录自己 ...

  8. angular.module()创建、获取、注册angular中的模块

    // 传递参数不止一个,代表新建模块;空数组代表该模块不依赖其他模块 var createModule = angular.module("myModule", []); // 只 ...

  9. Angular入门,开发环境搭建,使用Angular CLI创建你的第一个Angular项目

    前言: 最近一直在使用阿里的NG-ZORRO(Angular组件库)开发公司后端的管理系统,写了一段时间的Angular以后发现对于我们.NET后端开发而言真是非常的友善.因此这篇文章主要是对这段时间 ...

随机推荐

  1. [NOIP2013提高组]火柴排队

    题目:洛谷P1966.Vijos P1842.codevs3286. 题目大意:有两排火柴,每根都有一个高度.设a.b分别表示两排火柴的高度,现在要令$\sum(a_i-b_i)^2$最小.现两排火柴 ...

  2. python supper()函数

    参考链接:https://www.runoob.com/python/python-func-super.html super() 函数是用于调用父类(超类)的一个方法. class Field(ob ...

  3. ZJU 1346 Comparing Your Heroes 状态压缩DP 拓扑排序的计数

    做多校的时候遇见一个求拓扑排序数量的题,就顺便来写了一下. 题意: 你有个朋友是KOF的狂热粉丝,他有一个对其中英雄的强弱比较,让你根据这些比较关系来给这些英雄排名.问一共有多少种排名方式. 思路: ...

  4. windows server 打开 FTP 服务器上的文件夹时发生错误。请检查是否有权限访问该文件夹。

    解决方案1: 打开高级安全windows防火墙,设置出入站规则. 然后,再打开windows防火墙界面,点击左上角“允许程序或功能通过windows防火墙”,勾选上设置的出入站名称和FTP服务器. 如 ...

  5. 编程算法 - 篱笆修理(Fence Repair) 代码(C)

    篱笆修理(Fence Repair) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 把一块木板切成N块, 每次切两块, 分割的开销是木板长度, ...

  6. 【LeetCode-面试算法经典-Java实现】【063-Unique Paths II(唯一路径问题II)】

    [063-Unique Paths II(唯一路径问题II)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Follow up for "Unique Pa ...

  7. android ViewPager实现 跑马灯切换图片+多种切换动画

    近期在弄个项目.要求有跑马灯效果的图片展示. 网上搜了一堆,都没有完美实现的算了还是自己写吧! 实现原理利用 ViewPager 控件,这个控件本身就支持滑动翻页非常好非常强大好多功能都能用上它.利用 ...

  8. 2015上海网络赛 HDU 5478 Can you find it 数学

    HDU 5478 Can you find it 题意略. 思路:先求出n = 1 时候满足条件的(a,b), 最多只有20W对,然后对每一对进行循环节判断即可 #include <iostre ...

  9. ES6学习笔记(七)对象的新增方法

    1.Object.is() ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===).它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0.J ...

  10. js002---- 标准内置对象

    1. js全局的对象(全局作用域里的对象,而不是全局对象), 或者叫标准内置对象 2, 全局对象  是一个Global类的对象. 标准内置对象的分类: 1. 值属性 infinity       Na ...