我是Angular的初学者,我想知道如何创建Angular 5文件上传部分,我试图找到任何教程或文档,但我在任何地方都看不到任何东西。对此有什么想法吗?我尝试了ng4-files,但它不适用于Angular 5
当前回答
试试这个
安装
npm install primeng --save
进口
import {FileUploadModule} from 'primeng/primeng';
Html
<p-fileUpload name="myfile[]" url="./upload.php" multiple="multiple"
accept="image/*" auto="auto"></p-fileUpload>
其他回答
通过这种方式,我实现了在项目中上传文件到web API。
我为谁分担关心。
const formData: FormData = new FormData();
formData.append('Image', image, image.name);
formData.append('ComponentId', componentId);
return this.http.post('/api/dashboard/UploadImage', formData);
一步一步
ASP。网上广告
[HttpPost]
[Route("api/dashboard/UploadImage")]
public HttpResponseMessage UploadImage()
{
string imageName = null;
var httpRequest = HttpContext.Current.Request;
//Upload Image
var postedFile = httpRequest.Files["Image"];
//Create custom filename
if (postedFile != null)
{
imageName = new String(Path.GetFileNameWithoutExtension(postedFile.FileName).Take(10).ToArray()).Replace(" ", "-");
imageName = imageName + DateTime.Now.ToString("yymmssfff") + Path.GetExtension(postedFile.FileName);
var filePath = HttpContext.Current.Server.MapPath("~/Images/" + imageName);
postedFile.SaveAs(filePath);
}
}
HTML表单
<form #imageForm=ngForm (ngSubmit)="OnSubmit(Image)">
<img [src]="imageUrl" class="imgArea">
<div class="image-upload">
<label for="file-input">
<img src="upload.jpg" />
</label>
<input id="file-input" #Image type="file" (change)="handleFileInput($event.target.files)" />
<button type="submit" class="btn-large btn-submit" [disabled]="Image.value=='' || !imageForm.valid"><i
class="material-icons">save</i></button>
</div>
</form>
TS文件使用API
OnSubmit(Image) {
this.dashboardService.uploadImage(this.componentId, this.fileToUpload).subscribe(
data => {
console.log('done');
Image.value = null;
this.imageUrl = "/assets/img/logo.png";
}
);
}
服务TS
uploadImage(componentId, image) {
const formData: FormData = new FormData();
formData.append('Image', image, image.name);
formData.append('ComponentId', componentId);
return this.http.post('/api/dashboard/UploadImage', formData);
}
在我的情况下,我使用http拦截器,事情是,默认情况下,我的http拦截器设置内容类型头为应用程序/json,但对于文件上传,我使用multer库。 稍微改变一下我的http。interceptor定义,如果请求体是FormData,它会删除头,不触及访问令牌。 下面是一部分代码,它让我很开心。
if (request.body instanceof FormData) {
request = request.clone({ headers: request.headers.delete('Content-Type', 'application/json') });
}
if (request.body instanceof FormData) {
request = request.clone({ headers: request.headers.delete('Accept', 'application/json')});
}
create-profile.html
<body>
<h1 class="font-weight-bold" >Create Advertistment</h1>
<hr />
<form [formGroup]="form" (submit)="onSubmit()">
<div>
<label class="font-weight-bold">Insert Subject name</label>
<br>
<input formControlName="name" type="text" placeholder="Enter name..." />
</div>
<div>
<br>
<label class="font-weight-bold">Select the Advertistment</label>
<br>
<input (change)="onFileSelect($event)" type="file" />
</div>
<br>
<!--<div *ngIf="imageData">
<img [src]="imageData" [alt]="form.value.name" />
</div>-->
<div>
<label class="font-weight-bold">Upload the Advertistment</label>
<br>
<button type="submit" class="btn btn-success" >Upload Advertistment</button>
</div>
</form>
</body>
create-profile.ts
import { Component, OnInit } from "@angular/core";
import { FormGroup, FormControl } from "@angular/forms";
import { Profile } from "../../models/Profile";
import { ProfileService } from "src/app/services/profile.service";
@Component({
selector: "app-create-profile",
templateUrl: "./create-profile.component.html",
styleUrls: ["./create-profile.component.css"],
})
export class CreateProfileComponent implements OnInit {
form: FormGroup;
profile: Profile;
imageData: string;
constructor(private profileService: ProfileService) {}
ngOnInit(): void {
this.form = new FormGroup({
name: new FormControl(null),
image: new FormControl(null),
});
}
onFileSelect(event: Event) {
const file = (event.target as HTMLInputElement).files[0];
this.form.patchValue({ image: file });
const allowedMimeTypes = ["image/png", "image/jpeg", "image/jpg"];
if (file && allowedMimeTypes.includes(file.type)) {
const reader = new FileReader();
reader.onload = () => {
this.imageData = reader.result as string;
};
reader.readAsDataURL(file);
}
}
onSubmit() {
this.profileService.addProfile(this.form.value.name, this.form.value.image);
this.form.reset();
this.imageData = null;
}
}
profile.service.ts
import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { map } from "rxjs/operators";
import { Profile } from "../models/Profile";
import { Subject } from "rxjs";
@Injectable({
providedIn: "root",
})
export class ProfileService {
private profiles: Profile[] = [];
private profiles$ = new Subject<Profile[]>();
readonly url = "http://localhost:3000/api/profiles";
constructor(private http: HttpClient) {}
getProfiles() {
this.http
.get<{ profiles: Profile[] }>(this.url)
.pipe(
map((profileData) => {
return profileData.profiles;
})
)
.subscribe((profiles) => {
this.profiles = profiles;
this.profiles$.next(this.profiles);
});
}
getProfilesStream() {
return this.profiles$.asObservable();
}
addProfile(name: string, image: File): void {
const profileData = new FormData();
profileData.append("name", name);
profileData.append("image", image, name);
this.http
.post<{ profile: Profile }>(this.url, profileData)
.subscribe((profileData) => {
const profile: Profile = {
_id: profileData.profile._id,
name: name,
imagePath: profileData.profile.imagePath,
};
this.profiles.push(profile);
this.profiles$.next(this.profiles);
});
}
}
Profile.ts
export interface Profile {
_id: string;
name: string;
imagePath: string;
}
首先,你需要在你的Angular项目中设置HttpClient。
打开src/app/app.module。导入HttpClientModule并将其添加到模块的imports数组中,如下所示:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
接下来,生成一个组件:
$ ng generate component home
接下来,生成一个上传服务:
$ ng generate service upload
接下来,打开src/app/upload.service。Ts文件如下:
import { HttpClient, HttpEvent, HttpErrorResponse, HttpEventType } from '@angular/common/http';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class UploadService {
SERVER_URL: string = "https://file.io/";
constructor(private httpClient: HttpClient) { }
public upload(formData) {
return this.httpClient.post<any>(this.SERVER_URL, formData, {
reportProgress: true,
observe: 'events'
});
}
}
接下来,打开src/app/home/home.component.ts文件,开始添加以下导入:
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { HttpEventType, HttpErrorResponse } from '@angular/common/http';
import { of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { UploadService } from '../upload.service';
接下来,定义fileUpload和files变量,并注入UploadService,如下所示:
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
@ViewChild("fileUpload", {static: false}) fileUpload: ElementRef;files = [];
constructor(private uploadService: UploadService) { }
接下来,定义uploadFile()方法:
uploadFile(file) {
const formData = new FormData();
formData.append('file', file.data);
file.inProgress = true;
this.uploadService.upload(formData).pipe(
map(event => {
switch (event.type) {
case HttpEventType.UploadProgress:
file.progress = Math.round(event.loaded * 100 / event.total);
break;
case HttpEventType.Response:
return event;
}
}),
catchError((error: HttpErrorResponse) => {
file.inProgress = false;
return of(`${file.data.name} upload failed.`);
})).subscribe((event: any) => {
if (typeof (event) === 'object') {
console.log(event.body);
}
});
}
接下来,定义uploadFiles()方法,该方法可用于上传多个图像文件:
private uploadFiles() {
this.fileUpload.nativeElement.value = '';
this.files.forEach(file => {
this.uploadFile(file);
});
}
接下来,定义onClick()方法:
onClick() {
const fileUpload = this.fileUpload.nativeElement;fileUpload.onchange = () => {
for (let index = 0; index < fileUpload.files.length; index++)
{
const file = fileUpload.files[index];
this.files.push({ data: file, inProgress: false, progress: 0});
}
this.uploadFiles();
};
fileUpload.click();
}
接下来,我们需要创建图像上传UI的HTML模板。打开src/app/home/home.component.html文件,添加以下内容:
<div [ngStyle]="{'text-align':center; 'margin-top': 100px;}">
<button mat-button color="primary" (click)="fileUpload.click()">choose file</button>
<button mat-button color="warn" (click)="onClick()">Upload</button>
<input [hidden]="true" type="file" #fileUpload id="fileUpload" name="fileUpload" multiple="multiple" accept="image/*" />
</div>
看看这篇教程和这篇文章
使用Angular和nodejs上传文件的完整示例(express)
HTML代码
<div class="form-group">
<label for="file">Choose File</label><br/>
<input type="file" id="file" (change)="uploadFile($event.target.files)" multiple>
</div>
TS组件代码
uploadFile(files) {
console.log('files', files)
var formData = new FormData();
for(let i =0; i < files.length; i++){
formData.append("files", files[i], files[i]['name']);
}
this.httpService.httpPost('/fileUpload', formData)
.subscribe((response) => {
console.log('response', response)
},
(error) => {
console.log('error in fileupload', error)
})
}
Node Js代码
上传火灾控制器
function start(req, res) {
fileUploadService.fileUpload(req, res)
.then(fileUploadServiceResponse => {
res.status(200).send(fileUploadServiceResponse)
})
.catch(error => {
res.status(400).send(error)
})
}
module.exports.start = start
使用multer上传服务
const multer = require('multer') // import library
const moment = require('moment')
const q = require('q')
const _ = require('underscore')
const fs = require('fs')
const dir = './public'
/** Store file on local folder */
let storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public')
},
filename: function (req, file, cb) {
let date = moment(moment.now()).format('YYYYMMDDHHMMSS')
cb(null, date + '_' + file.originalname.replace(/-/g, '_').replace(/ /g, '_'))
}
})
/** Upload files */
let upload = multer({ storage: storage }).array('files')
/** Exports fileUpload function */
module.exports = {
fileUpload: function (req, res) {
let deferred = q.defer()
/** Create dir if not exist */
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir)
console.log(`\n\n ${dir} dose not exist, hence created \n\n`)
}
upload(req, res, function (err) {
if (req && (_.isEmpty(req.files))) {
deferred.resolve({ status: 200, message: 'File not attached', data: [] })
} else {
if (err) {
deferred.reject({ status: 400, message: 'error', data: err })
} else {
deferred.resolve({
status: 200,
message: 'File attached',
filename: _.pluck(req.files,
'filename'),
data: req.files
})
}
}
})
return deferred.promise
}
}
推荐文章
- 运行单个测试文件
- “declare”在“export declare class Actions”中做什么?
- NG6002:出现在NgModule中。导入AppModule类,但不能解析为NgModule类
- 向Angular HttpClient添加一个HTTP头并不会发送这个头,为什么?
- 不能绑定到'ngForOf',因为它不是'tr'的已知属性(最终版本)
- Angular中的全局事件
- Angular和Typescript:不能找到名字——错误:不能找到名字
- HttpModule和HttpClientModule的区别
- 禁用响应式输入字段
- 'this'隐式具有类型'any',因为它没有类型注释
- 带有用户单击所选组件的动态选项卡
- 在TypeScript中声明抽象方法
- 如何强制tsc忽略node_modules文件夹?
- TypeScript for…的索引/键?
- 如何在Typescript中获得一个变量类型?