[AngularFire] Angular File Uploads to Firebase Storage with Angular control value accessor
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的更多相关文章
- [Angular] Implement a custom form component by using control value accessor
We have a form component: <label> <h3>Type</h3> <workout-type formControlName=& ...
- [转]File uploads in ASP.NET Core
本文转自:https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads By Steve Smith ASP.NET MVC ...
- 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 ...
- 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 ...
- 从Java角度理解Angular之入门篇:npm, yarn, Angular CLI
本系列从Java程序员的角度,带大家理解前端Angular框架. 本文重点介绍Angular的开发.编译工具:npm, yarn, Angular CLI,它们就像Java在中的Maven,同时顺便介 ...
- (转载)从Java角度理解Angular之入门篇:npm, yarn, Angular CLI
本系列从Java程序员的角度,带大家理解前端Angular框架. 本文是入门篇.笔者认为亲自动手写代码做实验,是最有效最扎实的学习途径,而搭建开发环境是学习一门新技术最需要先学会的技能,是入门的前提. ...
- Angular 个人深究(一)【Angular中的Typescript 装饰器】
Angular 个人深究[Angular中的Typescript 装饰器] 最近进入一个新的前端项目,为了能够更好地了解Angular框架,想到要研究底层代码. 注:本人前端小白一枚,文章旨在记录自己 ...
- angular.module()创建、获取、注册angular中的模块
// 传递参数不止一个,代表新建模块;空数组代表该模块不依赖其他模块 var createModule = angular.module("myModule", []); // 只 ...
- Angular入门,开发环境搭建,使用Angular CLI创建你的第一个Angular项目
前言: 最近一直在使用阿里的NG-ZORRO(Angular组件库)开发公司后端的管理系统,写了一段时间的Angular以后发现对于我们.NET后端开发而言真是非常的友善.因此这篇文章主要是对这段时间 ...
随机推荐
- [NOIP2013提高组]火柴排队
题目:洛谷P1966.Vijos P1842.codevs3286. 题目大意:有两排火柴,每根都有一个高度.设a.b分别表示两排火柴的高度,现在要令$\sum(a_i-b_i)^2$最小.现两排火柴 ...
- python supper()函数
参考链接:https://www.runoob.com/python/python-func-super.html super() 函数是用于调用父类(超类)的一个方法. class Field(ob ...
- ZJU 1346 Comparing Your Heroes 状态压缩DP 拓扑排序的计数
做多校的时候遇见一个求拓扑排序数量的题,就顺便来写了一下. 题意: 你有个朋友是KOF的狂热粉丝,他有一个对其中英雄的强弱比较,让你根据这些比较关系来给这些英雄排名.问一共有多少种排名方式. 思路: ...
- windows server 打开 FTP 服务器上的文件夹时发生错误。请检查是否有权限访问该文件夹。
解决方案1: 打开高级安全windows防火墙,设置出入站规则. 然后,再打开windows防火墙界面,点击左上角“允许程序或功能通过windows防火墙”,勾选上设置的出入站名称和FTP服务器. 如 ...
- 编程算法 - 篱笆修理(Fence Repair) 代码(C)
篱笆修理(Fence Repair) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 把一块木板切成N块, 每次切两块, 分割的开销是木板长度, ...
- 【LeetCode-面试算法经典-Java实现】【063-Unique Paths II(唯一路径问题II)】
[063-Unique Paths II(唯一路径问题II)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Follow up for "Unique Pa ...
- android ViewPager实现 跑马灯切换图片+多种切换动画
近期在弄个项目.要求有跑马灯效果的图片展示. 网上搜了一堆,都没有完美实现的算了还是自己写吧! 实现原理利用 ViewPager 控件,这个控件本身就支持滑动翻页非常好非常强大好多功能都能用上它.利用 ...
- 2015上海网络赛 HDU 5478 Can you find it 数学
HDU 5478 Can you find it 题意略. 思路:先求出n = 1 时候满足条件的(a,b), 最多只有20W对,然后对每一对进行循环节判断即可 #include <iostre ...
- ES6学习笔记(七)对象的新增方法
1.Object.is() ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===).它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0.J ...
- js002---- 标准内置对象
1. js全局的对象(全局作用域里的对象,而不是全局对象), 或者叫标准内置对象 2, 全局对象 是一个Global类的对象. 标准内置对象的分类: 1. 值属性 infinity Na ...