javascript - 如何使用 Angular 6 实现文件上传?
问题描述
我试图在女巫中创建一个组件,我在一个子组件中实现了文件上传功能,然后我试图在另一个组件中使用该组件的选择器:我的项目结构是这样的:
- upload :
upload.component.html
upload.component.ts
upload.module.ts
在这个包中我实现了这个代码:upload.component.html:
<div class="row">
<div class="col-12">
<ngfFormData [files]="files" postName="file" [(FormData)]="sendableFormData"></ngfFormData>
<ngfUploadStatus [(percent)]="progress" [httpEvent]="httpEvent"></ngfUploadStatus>
<div class="inline-block">
</div>
<div>
<h3>Drop Files</h3>
<div class="border padding-15 border-radius bg-white mb-2">
<div class="inline-block">
<div ngfDrop [(validDrag)]="baseDropValid" (fileOver)="hasBaseDropZoneOver=$event" [(files)]="files" [accept]="accept" [maxSize]="maxSize"
[(dragFiles)]="dragFiles" [(lastInvalids)]="lastInvalids" class="well my-drop-zone" [class.invalid-drag]="baseDropValid===false"
[class.valid-drag]="baseDropValid" (filesChange)="lastFileAt=getDate()">
<p class="font">Glisser/Déposer le document ou choisir un document...</p>
</div>
</div>
</div>
</div>
<div class="inline-block">
<strong>maxSize in bytes</strong>
<div>
<input type="number" [(ngModel)]="maxSize" placeholder="1024 == 1mb" />
</div>
</div>
<div *ngIf="dragFiles">
<h3 style="margin:0">Drag Files</h3>
<p *ngIf="!dragFiles.length" style="color:red;">
This browser does NOT release metadata for files being dragged. All files will be considered valid drags until dropped.
</p>
<pre>{{ dragFiles | json }}</pre>
</div>
<div class="bg-warning" *ngIf="lastInvalids?.length" style="margin-bottom: 40px">
<h3 style="color:red;">Last {{ lastInvalids.length }} Invalid Selected Files</h3>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Error</th>
<th>Type</th>
<th>Size</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of lastInvalids;let i=index">
<td>
<div *ngIf="['image/gif','image/png','image/jpeg'].indexOf(item.file.type)>=0">
<div class="previewIcon" [ngfBackground]="item.File"></div>
</div>
<strong>{{ item.file.name }}</strong>
</td>
<td nowrap>
{{ item.type }}
</td>
<td nowrap>
{{ item.file.type }}
</td>
<td nowrap>
{{ item.file.size/1024/1024 | number:'.2' }} MB
</td>
<td nowrap>
<button type="button" class="btn btn-danger btn-xs" (click)="lastInvalids.splice(i,1)">
<span class="glyphicon glyphicon-trash"></span>
</button>
</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-bottom: 40px">
<h3>{{ files.length }} Queued Files</h3>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Size</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of files;let i=index">
<td>
<div *ngIf="['image/gif','image/png','image/jpeg'].indexOf(item.type)>=0">
<div class="previewIcon" [ngfBackground]="item"></div>
</div>
<strong>{{ item.name }}</strong>
</td>
<td nowrap>
{{ item.type }}
</td>
<td nowrap>
{{ item.size/1024/1024 | number:'.2' }} MB
</td>
<td nowrap>
<i class="icons icon-file_delete pointer" (click)="files.splice(i,1)"></i>
</td>
</tr>
</tbody>
</table>
<div>
<div>
Queue progress:
<div class="progress" style="">
<div class="progress-bar" role="progressbar" [ngStyle]="{ 'width': progress + '%' }"></div>
</div>
</div>
<ng-container *ngIf="lastFileAt">
<p>
<strong>Last file(s) selected At:</strong> {{ lastFileAt | date : 'longTime' }}
</p>
</ng-container>
<i *ngIf="progress==100" class="glyphicon glyphicon-ok"></i>
<button (click)="uploadFiles(files)" >
Upload all
</button>
<button (click)="cancel()" >
Cancel all
</button>
<button (click)="files.length=0" >
Remove all
</button>
</div>
</div>
</div>
上传.component.ts :
import { Component, OnInit, NgModule } from '@angular/core';
import { ngfModule, ngf } from "angular-file";
import {
HttpClient, HttpRequest, HttpResponse, HttpEvent
} from "@angular/common/http";
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { BrowserModule } from '@angular/platform-browser';
import { Subscription } from 'rxjs';
@Component({
selector: 'sof-upload',
templateUrl: './upload.component.html',
styleUrls: ['./upload.component.scss']
})
export class UploadComponent implements OnInit {
accept = '*'
files:File[] = []
progress:number
url = 'https://evening-anchorage-3159.herokuapp.com/api/'
hasBaseDropZoneOver:boolean = false
httpEmitter:Subscription
httpEvent:HttpEvent<{}>
lastFileAt:Date
sendableFormData:FormData//populated via ngfFormData directive
constructor(public HttpClient:HttpClient) { }
cancel(){
this.progress = 0
if( this.httpEmitter ){
console.log('cancelled')
this.httpEmitter.unsubscribe()
}
}
uploadFiles(files:File[]):Subscription{
const req = new HttpRequest<FormData>('POST', this.url,
this.sendableFormData, {
reportProgress: true//, responseType: 'text'
})
return this.httpEmitter = this.HttpClient.request(req)
.subscribe(
event=>{
this.httpEvent = event
if (event instanceof HttpResponse) {
delete this.httpEmitter
console.log('request done', event)
}
},
error=>console.log('Error Uploading',error)
)
}
getDate(){
return new Date()
}
ngOnInit() {
}
}
上传.module.ts:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { UploadComponent } from './upload.component';
@NgModule({
imports: [
CommonModule,
],
declarations: [UploadComponent],
providers: [],
exports: [UploadComponent]
})
export class UploadModule { }
然后我尝试在另一个组件中调用它的选择器,所以我只是创建了该组件并添加了:
<sof-upload></sof-upload>
我在我的 app.module.ts 中添加了第一个组件模块,但我得到了这个我无法解决的错误:
Uncaught Error: Template parse errors:
Can't bind to 'files' since it isn't a known property of 'ngfFormData'. ("
<ngfFormData [ERROR ->][files]="files" postName="file" [(FormData)]="sendableFormData"></ngfFormData>
<ngfUploadS"): ng:///UploadModule/UploadComponent.html@4:19
Can't bind to 'FormData' since it isn't a known property of 'ngfFormData'. ("
<ngfFormData [files]="files" postName="file" [ERROR ->][(FormData)]="sendableFormData"></ngfFormData>
<ngfUploadStatus [(percent)]="progress" [ht"): ng:///UploadModule/UploadComponent.html@4:51
'ngfFormData' is not a known element:
1. If 'ngfFormData' is an Angular component, then verify that it is part of this module.
2. To allow any element add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component. ("
[ERROR ->]<ngfFormData [files]="files" postName="file" [(FormData)]="sendableFormData"></ngfFormData>
"): ng:///UploadModule/UploadComponent.html@4:6
Can't bind to 'percent' since it isn't a known property of 'ngfUploadStatus'. ("="files" postName="file" [(FormData)]="sendableFormData"></ngfFormData>
<ngfUploadStatus [ERROR ->][(percent)]="progress" [httpEvent]="httpEvent"></ngfUploadStatus>
解决方案
刚刚通过将 ngfModule 添加到子模块的导入中解决了这个问题。很好的例子,所以喜欢尝试它。
推荐阅读
- r - ROC 逐步回归
- python - 如何使用python对单个矩阵值求平方?
- python-2.7 - 如何在页面上获取元素,单击其他内容并等待原始元素消失
- mongodb - 删除与某个元素匹配的数组元素
- html - Spring Boot:如何在 Spring Boot 应用程序中显示系统目录中的图像?
- python - list(frozenset()) 返回的元素顺序是如何确定的?
- java - 如何获取 Foo 类型的类实例
(富 .class 不起作用) - html - CSS改变边框的颜色两次,同时赋予它从左到右的效果
- java - 为什么下面程序的输出是 25?
- selenium - 为什么我收到以下错误“元素类型侦听器的内容必须匹配(侦听器)*”?