在做移动端开发多时候经常会遇到用户图片上传的需求,有单图片上传预览的需求,也有多图片上传预览的需求。自己刚遇到这个需求的时候有踩到各种个样到坑。经过多番尝试,下面将本人成功的一个案例分享出来(公司对外网访问非常严格,所以只能自己重写一个demo来摆弄,亲测可行):
1、先在我们的项目通过cli命令行创建出我们要实现上传文件的组件:
ng generate component fileReader
复制代码
在file-reader.component.html
文件的html代码如下:
<label class="preview-btn">浏览图片
<input type="file" appFileReader (onLoad)="addLoad($event)" multiple style="display:none"/>
</label>
<div *ngIf="previewImg.length > 0">
<img *ngFor="let img of previewImg" src="{{img}}" alt="">
</div>
<br>
<button *ngIf="previewImg.length > 0" (click)="clearPreviewImg()" class="preview-btn">清除图片</button>
复制代码
在file-reader.component.scss
样式文件对按钮对样式稍加美化:
.preview-btn{
width: 100px;
border-radius: 4px;
height: 36px;
line-height: 36px;
background-color: greenyellow;
color: #fff;
text-align: center;
display: block;
cursor: pointer;
border: none;
outline: none;
}
复制代码
file-reader.component.ts
里面的代码如下:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-file-reader',
templateUrl: './file-reader.component.html',
styleUrls: ['./file-reader.component.scss'],
})
export class FileReaderComponent implements OnInit {
previewImg: Array<string> = [];
constructor() { }
ngOnInit() {
}
addLoad(e: string) {
this.previewImg.push(e);
}
clearPreviewImg() {
this.previewImg = [];
}
}
复制代码
2、然后通过cli命令创建出我们要实现上传预览功能的自定义指令:
ng generate directive fileReader
复制代码
创建的文件file-reader.directive.ts逻辑代码如下,具体的功能代码也有相应的注释
import { Directive, ElementRef, HostListener, Output, EventEmitter } from '@angular/core';
/**
* 图片选择转换成base64
*/
@Directive({
selector: '[appFileReader]'
})
export class FileReaderDirective {
// tslint:disable-next-line: no-output-on-prefix
@Output()
onLoad = new EventEmitter();
constructor(private elementRef: ElementRef) { }
/**
* HostListener给宿主元素添加change事件
* 获取到的files是一个文件列表,不能直接遍历,需要先Array.from转数组类型
*/
@HostListener('change')
public onChange(): any {
const files = this.elementRef.nativeElement.files;
if (files && files.length > 0) {
Array.from(files).map((item: File, index: number) => {
const file: File = item;
const myReader: FileReader = new FileReader();
/**
* onabort 当读取操作被中止时调用
* onerror 当读取操作发生错误时调用
* onload 当读取操作成功完成时调用
* onloadend 当读取操作完成时调用,不管是成功还是失败.该处理程序在onload或者onerror之后调用
* onloadstart 当读取操作将要开始之前调用
* onprogress 在读取数据过程中周期性调用
*/
myReader.onloadend = (loadEvent: any) => {
this.onLoad.emit(loadEvent.target.result);
};
/**
* readAsBinaryString(file) 将文件读取为二进制编码
* readAsText(file,[encoding]) 将文件读取为文本
* readAsDataURL(file) 将文件读取为DataURL
* abort(none) 终端读取操作
*/
myReader.readAsDataURL(file);
});
}
}
}
复制代码
到这一步我们就基本已经把angular2+自定义指令实现多图片上传预览
这一个功能完成了。接下来要怎么玩就看大家的具体需求是怎样子的了,反正预览的图片数据已经拿到。
第一次写博客,有不完善的地方希望各位大佬不要吝啬给出意见。