单击添加按钮时,角度选择多个文件而不上传和上传
Posted
技术标签:
【中文标题】单击添加按钮时,角度选择多个文件而不上传和上传【英文标题】:Angular select multiple files without uploading and upload when clicking add button 【发布时间】:2019-09-24 05:31:36 【问题描述】:我有一个用于添加房屋的添加模式组件。当我按下添加房屋时,我会得到一个要填写的模式表格,并且有一个名为上传文件的按钮 我有一个上传组件,我可以在其中选择多个文件并上传。 比我必须填写其他信息并单击添加以添加房屋。 但我想选择文件而不直接上传它们,只有在我点击添加房屋按钮时才上传文件。
UploadComponent.ts
import Component, OnInit, EventEmitter, Output from '@angular/core';
import HttpEventType, HttpClient from '@angular/common/http';
@Component(
selector: 'app-upload',
templateUrl: './upload.component.html',
styleUrls: ['./upload.component.scss']
)
export class UploadComponent implements OnInit
public imagePath;
imgURL: any;
public progress: number;
public message: string;
public files = []; @Output() public onUploadFinished = new EventEmitter();
constructor(private http: HttpClient)
ngOnInit()
public uploadFile = (files: File[]) =>
if (files.length === 0)
return;
const formData = new FormData();
for (let i = 0; i < files.length; i++)
const fileToUpload = files[i];
formData.append('file', fileToUpload, fileToUpload.name);
this.http.post('https://localhost:5001/api/upload', formData, reportProgress: true, observe: 'events')
.subscribe(event =>
if (event.type === HttpEventType.UploadProgress)
this.progress = Math.round(100 * event.loaded / event.total);
else if (event.type === HttpEventType.Response)
this.message = 'Upload success.';
this.onUploadFinished.emit(event.body);
);
// Preview image before upload
const reader = new FileReader();
this.imagePath = files;
reader.readAsDataURL(files[0]);
reader.onload = (_event) =>
this.imgURL = reader.result;
;
上传组件.html
<div class="row" style="margin-bottom:15px;">
<div class="col-md-3">
<img [src]="imgURL" *ngIf="imgURL">
<input type="file" #file placeholder="Choose file" multiple (change)="uploadFile(file.files)" style="display:none;">
<button type="button" class="btn btn-success" (click)="file.click()" >Upload File</button>
</div>
<div class="col-md-4">
</div>
</div>
AddModalComponent.ts
import Component, OnInit, ViewChild, TemplateRef from '@angular/core';
import FormControl, FormGroup, Validators, FormBuilder from '@angular/forms';
import BsModalService from 'ngx-bootstrap';
import HouseService from 'app/services/house.service';
import HttpEventType, HttpClient from '@angular/common/http';
import ModalService from 'app/services/modal.service';
import FormControlsService from 'app/services/form-controls.service';
@Component(
selector: 'app-add-modal',
templateUrl: './add-modal.component.html',
styleUrls: ['./add-modal.component.css']
)
export class AddModalComponent implements OnInit
public response: dbPath: '';
// Add Modal
@ViewChild('template') modal: TemplateRef<any>;
constructor(
public modalProp: ModalService,
private modalService: BsModalService,
private houseService: HouseService,
private fb: FormBuilder,
public fc: FormControlsService
)
ngOnInit()
const validateImageUrl = '^(https?:\/\/.*\.(?:png|jpg))$';
this.fc.name = new FormControl('', [Validators.required, Validators.maxLength(50)]);
this.fc.price = new FormControl('', [Validators.required, Validators.min(0), Validators.max(10000)]);
this.fc.description = new FormControl('', [Validators.required, Validators.maxLength(150)]);
this.fc.imageUrl = new FormControl('', []);
this.fc.insertForm = this.fb.group(
name : this.fc.name,
price : this.fc.price,
description : this.fc.description,
imageUrl : this.fc.imageUrl,
avalaible : true,
);
onAddHouse()
this.modalProp.modalRef = this.modalService.show(this.modal);
public uploadFinished = (event) =>
this.response = event;
this.fc.imageUrl.setValue(this.response.dbPath);
// Method to Add new Product
onSubmit()
const newProduct = this.fc.insertForm.value;
this.houseService.insertHouse(newProduct).subscribe(
result =>
this.houseService.clearCache();
this.modalProp.houses$ = this.houseService.getHouses();
this.modalProp.houses$ .subscribe(newlist =>
this.modalProp.houses = newlist;
this.modalProp.modalRef.hide();
this.fc.insertForm.reset();
// this.rerender();
);
console.log('New Product added');
,
error => console.log('Could not add Product')
);
AddModalComponent.html
<!-- ADD HOUSE MODAL START-->
<button class="btn btn-warning mb-3 float-right text-uppercase" *ngIf="modalProp.userRoleStatus == 'Admin'" (click)="onAddHouse()" ><i class="fa fa-plus"></i> Huis toevoegen</button><br>
<ng-template #template>
<div class="modal-header">
<h4 class="modal-title">ADD NEW HOUSE</h4>
<button type="button" class="close pull-right" aria-label="Close" (click)="modalProp.modalRef.hide()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body text-center">
<p class="list-group-item active text-center text-uppercase"></p>
<form [formGroup]="fc.insertForm" (ngSubmit)="onSubmit()">
<ul class="list-group">
<li class="list-group-item">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="houseTitle"><i class="fa fa-pencil-square-o"></i></span>
</div>
<input type="text" id="name" formControlName="name" class="form-control" placeholder="Stad" aria-label="name" aria-describedby="houseTitle">
</div>
<div *ngIf="fc.name.touched && fc.name.errors" class="errorMessage" >
<span *ngIf="fc.name.hasError('required')">City Name is required.</span>
<span *ngIf="fc.name.hasError('maxlength')">Only 50 characters allowed for House Name.</span>
</div>
</li>
<li class="list-group-item">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="houseDescription"><i class="fa fa-pencil-square-o"></i></span>
</div>
<textarea formControlName="description" class="form-control" placeholder="Beschrijf het huis - Max 150 Tekens" aria-label="Description" aria-describedby="houseDescription"></textarea>
</div>
<div class="errorMessage" *ngIf="fc.description.touched && fc.description.errors">
<span *ngIf="fc.description.hasError('required')">House Description is required.</span>
<span *ngIf="fc.description.hasError('maxlength')">Only 150 characters allowed for House Description.</span>
</div>
</li>
<!-- <li class="list-group-item">
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text">
<input type="checkbox" formControlName="available" checked aria-label="Checkbox for following text input">
</div>
</div>
<input type="text" class="form-control" placeholder="House available" disabled>
</div>
</li> -->
<li class="list-group-item">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-usd"></i></span>
</div>
<input formControlName="price" type="text" class="form-control" placeholder="Prijs">
</div>
<div class="errorMessage" *ngIf="fc.price.touched && fc.price.errors">
<span *ngIf="fc.price.hasError('required')">House Price is required.</span>
<span *ngIf="fc.price.hasError('min')" >Negative price Not allowed</span>
<span *ngIf="fc.price.hasError('max')">Max price allowes is 10000</span>
</div>
</li>
<li class="list-group-item">
<app-upload (onUploadFinished)="uploadFinished($event)"></app-upload>
</li>
<li class="list-group-item">
<button [disabled]="fc.insertForm.invalid" class="btn btn-primary btn-block">ADD</button>
</li>
</ul>
</form>
</div>
</ng-template>
<!-- ADD HOUSE MODAL START-->
【问题讨论】:
【参考方案1】:使用 Angular 上传多个文件:
在组件(TS)中声明选择的文件属性(我们稍后会用到):
export class SomeComponent
selectedFile: FileList | [] = [];
//...
这是图片上传的 HTML:
<form>
<input
style="display: none"
type="file" name="images" (change)="onFileChanged($event)" #fileInput multiple="multiple">
<button type="button" (click)="fileInput.click()">Select Files</button>
<button type="button" (click)="onUpload()">Upload!</button>
</form>
注意style="display: none"
是隐藏字段,所以只有按钮可见。
#fileInput
指向输入元素并被按钮用于在单击按钮时单击元素:fileInput.click()
。
返回组件:
onFileChanged(event: any)
this.selectedFiles = event.target.files;
console.log(this.selectedFiles);
onUpload()
//Here you send 'this.selectedFiles' to the server..
TL;DR(太长;未阅读)
这部分真正使多个文件上传可用的是:
输入字段上的multiple="multiple"
。
【讨论】:
【参考方案2】:您可以只使用一个简单的数组来推送文件,然后在提交时迭代该数组并进行发布...
filesToUpload = [];
// called on file chosen
handleFileInput(files: FileList)
this.filesToUpload.push(files[0]);
并在提交迭代文件并制作表单数据时,或者使用forkJoin
并行运行请求。
const reqs = [];
this.filesToUpload.forEach(x =>
const formData = new FormData();
formData.append('file', x);
// add your function
reqs.push(this.myService.doSomething(formData)));
);
forkJoin(reqs).subscribe(......)
【讨论】:
以上是关于单击添加按钮时,角度选择多个文件而不上传和上传的主要内容,如果未能解决你的问题,请参考以下文章