2016-03-14 46 views
34

我必须随图像一起提交表单。我试过这个代码(有多种方式),但没有为我工作。有没有人有使用angular2的文件上传工作演示,请帮助我。如何在Angular2中上传文件

component.html

<form class="form-horizontal" role="form" > 

     <div class="form-group"> 
      <label class="control-label col-sm-4" for="myname" style="">Name<span class="asterisk">*</span></label> 
      <div class="col-sm-7"> 
       <div> 
        <input type="text" class="form-control" id="myname" 
        [(ngModel)]="myfile.name">       
       </div>     
      </div>        
     </div>   


     <div class="form-group"> 
      <label class="control-label col-sm-4" for="myimage">Image</label> 
      <div class="col-sm-7"> 
       <div> 
        <input type="file" (change)="fileChangeEvent($event)" placeholder="Upload file..." />       
       </div> 
      </div> 
     </div> 


     <div class="form-group">   
     <div class="text-center"> 
      <button type="button" (click)="upload()">Upload</button>    
     </div> 
     </div> 
    </form> 

component.ts

 myfile={ 
       "name":"Mubashshir",    
       "image":'' 
    } 

    fileChangeEvent(fileInput: any){ 
     this.myfile.image = fileInput.target.files;   
    } 

    upload(){ 
      this.base_path_service.PostRequest('http://128.199.190.109/api/school/schoolDetail/',this.myfile) 
      .subscribe(
       data => { 
          console.log("data submitted");       
         }, 
       err => console.log(err), 
       () =>{ 
        console.log('Authentication Complete');      

       } 
      ); 
     } 
+0

看到http://stackoverflow.com/a/39862337/3779853 – Blauhirn

回答

23

事实上,Http类不支持的时刻。

你需要利用底层的XHR对象做到这一点:

import {Injectable} from 'angular2/core'; 
import {Observable} from 'rxjs/Rx'; 

@Injectable() 
export class UploadService { 
    constructor() { 
    this.progress$ = Observable.create(observer => { 
     this.progressObserver = observer 
    }).share(); 
    } 

    private makeFileRequest (url: string, params: string[], files: File[]): Observable { 
    return Observable.create(observer => { 
     let formData: FormData = new FormData(), 
     xhr: XMLHttpRequest = new XMLHttpRequest(); 

     for (let i = 0; i < files.length; i++) { 
     formData.append("uploads[]", files[i], files[i].name); 
     } 

     xhr.onreadystatechange =() => { 
     if (xhr.readyState === 4) { 
      if (xhr.status === 200) { 
      observer.next(JSON.parse(xhr.response)); 
      observer.complete(); 
      } else { 
      observer.error(xhr.response); 
      } 
     } 
     }; 

     xhr.upload.onprogress = (event) => { 
     this.progress = Math.round(event.loaded/event.total * 100); 

     this.progressObserver.next(this.progress); 
     }; 

     xhr.open('POST', url, true); 
     xhr.send(formData); 
    }); 
    } 
} 

请参阅本plunkr了解更多详情:https://plnkr.co/edit/ozZqbxIorjQW15BrDFrg?p=info

有一个问题,并在角回购对此挂起PR:

+0

试过这个,但在CORS中不工作 –

+0

你怎么能得到这个回应?难道现在不应该成为一个Promise而不是Observable吗? – Juicy

+0

嘿,即时通讯解析这个答案erros。 EXCEPTION:SyntaxError:JSON.parse:JSON datavendor.js第1行第1列的意外字符:1617 EXCEPTION:SyntaxError:JSON.parse:JSON数据行1列1处的意外字符datavendor.js:1617:2286 STACKTRACE:vendor.js:1617:2286 ................其他人得到这个问题? – John

16

你的HTTP服务的文件:

import { Injectable } from "@angular/core"; 
import { ActivatedRoute, Router } from '@angular/router'; 
import { Http, Headers, Response, Request, RequestMethod, URLSearchParams, RequestOptions } from "@angular/http"; 
import {Observable} from 'rxjs/Rx'; 
import { Constants } from './constants'; 
declare var $: any; 

@Injectable() 
export class HttpClient { 
    requestUrl: string; 
    responseData: any; 
    handleError: any; 

    constructor(private router: Router, 
    private http: Http, 
    private constants: Constants, 
) { 
    this.http = http; 
    } 

    postWithFile (url: string, postData: any, files: File[]) { 

    let headers = new Headers(); 
    let formData:FormData = new FormData(); 
    formData.append('files', files[0], files[0].name); 
    // For multiple files 
    // for (let i = 0; i < files.length; i++) { 
    //  formData.append(`files[]`, files[i], files[i].name); 
    // } 

    if(postData !=="" && postData !== undefined && postData !==null){ 
     for (var property in postData) { 
      if (postData.hasOwnProperty(property)) { 
       formData.append(property, postData[property]); 
      } 
     } 
    } 
    var returnReponse = new Promise((resolve, reject) => { 
     this.http.post(this.constants.root_dir + url, formData, { 
     headers: headers 
     }).subscribe(
      res => { 
      this.responseData = res.json(); 
      resolve(this.responseData); 
      }, 
      error => { 
      this.router.navigate(['/login']); 
      reject(error); 
      } 
    ); 
    }); 
    return returnReponse; 
    } 
} 

调用函数(组件文件):

onChange(event) { 
    let file = event.srcElement.files; 
    let postData = {field1:"field1", field2:"field2"}; // Put your form data variable. This is only example. 
    this._service.postWithFile(this.baseUrl + "add-update",postData,file).then(result => { 
     console.log(result); 
    }); 
} 

您的html代码:

<input type="file" class="form-control" name="documents" (change)="onChange($event)" [(ngModel)]="stock.documents" #documents="ngModel"> 
+0

这不起作用,因为http post不支持FormData ,你的数据将不会被传递到服务器,https://github.com/angular/angular/issues/13241 – kolexinfos

3

改进的onChange()方法:

file: File; 
    onChange(event: EventTarget) { 
     let eventObj: MSInputMethodContext = <MSInputMethodContext> event; 
     let target: HTMLInputElement = <HTMLInputElement> eventObj.target; 
     let files: FileList = target.files; 
     this.file = files[0]; 
     console.log(this.file); 
    } 
+0

最后,我有一个文件对象! – Belter

0

Here is the Angular 2 version

我们需要实施在我们的之一拖放文件输入功能应用程序。

我们为此选择了ng-file-upload

我们试着按照help page。至于建议,实施drag-upload-input.html & drag-upload-input.component.ts类似如下:

拖上载input.html

<!-- we only need single file upload --> 
<input type="file" ng2FileSelect [uploader]="uploader" /> 

拖上载input.component。TS

import { Component } from '@angular/core'; 
import { FileUploader } from 'ng2-file-upload'; 

// const URL = '/api/'; 
const URL = 'https://evening-anchorage-3159.herokuapp.com/api/'; 

@Component({ 
    moduleId: module.id, 
    selector: 'drag-upload-input', 
    templateUrl: './drag-upload-input.html' 
}) 
export class DragUploadInput { 
    public uploader: FileUploader = new FileUploader({ url: URL }); 
    public hasBaseDropZoneOver: boolean = false; 
    public hasAnotherDropZoneOver: boolean = false; 

    public fileOverBase(e: any): void { 
    this.hasBaseDropZoneOver = e; 
    } 

    public fileOverAnother(e: any): void { 
    this.hasAnotherDropZoneOver = e; 
    } 
} 

app.module.ts得到了FileUploadModule这样的:

// File upload modules 
import { FileUploadModule } from 'ng2-file-upload'; 
import { DragUploadInput } from './file-upload/drag-upload-input.component'; 

//other imports 

@NgModule({ 
    imports: [ ... other imports 
FileUploadModule 
], 
    declarations: [ ... other declarations 
DragUploadInput], 
    bootstrap: [AppComponent] 
}) 
export class AppModule { } 

而且systemjs.config.js看起来是这样的:

(function (global) { 
    System.config({ 
    // map tells the System loader where to look for things 
    map: { 
     // other libraries 
     'ng2-file-upload': 'node_modules/ng2-file-upload', 
    }, 
    packages: { 
     // other packages 
     ng2-file-upload': { 
     main: 'ng2-file-upload.js', 
     defaultExtension: 'js' 
     } 
    } 
    }); 
})(this); 

source

+0

嘿,文件上传到哪里?我们如何配置它? – haifzhan