2016-04-03 9 views
4

Ich entwickle gerade in Angular 2 ein Formular, mit dem ein Benutzer sein Profil aktualisieren kann: E-Mail und Passwort.Angular 2 - Modellgesteuertes Formular mit Eingabedatei (Datei-Upload)

benutzer edit.component.html:

<form novalidate="novalidate" [ngFormModel]="form" (ngSubmit)="form.valid && onSubmit()"> 
    <fieldset> 
     <div> 
      <label for="email"> 
       Email 
      </label> 

      <input id="email" type="email" #email="ngForm" ngControl="email"/> 

      <div class="error" *ngIf="email.control.hasError('required') && email.touched"> 
       This value is required. 
      </div> 
     </div> 

     <div> 
      <label for="password"> 
       Password 
      </label> 

      <input id="password" type="password" #password="ngForm" ngControl="password"/> 

      <div class="error" *ngIf="password.control.hasError('required') && password.touched"> 
       This value is required. 
      </div> 
     </div> 
    </fieldset> 

    <button type="submit" [disabled]="!form.valid"> 
     Save 
    </button> 
</form> 

benutzer edit.component.ts:

@Component({ 
    selector: 'user-edit', 
    templateUrl: 'app/components/user-edit/user-edit.component.html', 
}) 
export class UserEditComponent implements OnInit { 
    form: any; 

    errors = []; 

    constructor(
     private _formBuilder: FormBuilder, 
     private _router: Router, 
     private _userService: UserService 
    ) {} 

    ngOnInit() { 
     this.form = this._formBuilder.group({ 
      'email': ['', Validators.required)], 
      'password': ['', Validators.required], 
     }); 
    } 

    onSubmit() { 
     var self = this; 

     this._userService.edit(this.form.value, function (response: Response) { 
      console.log('OK'); 
     }, function (response: Response) { 
      console.log('ERROR'); 
     }); 
    } 
} 

user.service.ts:

@Injectable() 
export class UserService { 
    constructor (
     private _http: Http 
    ) {} 

    edit(user: User, cfOnNext?: Function, cfOnError?: Function): void { 
     let body = JSON.stringify(user); 
     let headers = new Headers({ 
      'Content-Type': 'application/json', 
     }); 
     let options = new RequestOptions({ 
      headers: headers, 
     }); 

     self._http.put('https://api.dom/me', body, options).subscribe(function (response) { 
      if (cfOnNext) { 
       cfOnNext(response); 
      } 
     }, function (response) { 
      if (cfOnError) { 
       cfOnError(response); 
      } 
     }); 
    } 
} 

Heute möchte ich um das Hochladen eines Fotos zu ermöglichen, indem einfach ein Dateitypfeld hinzugefügt wird.

Aber ich fand sehr wenig Informationen zu diesem Thema.

Die einzige Lösung scheint hier tun, was ich will zu nähern ist: https://www.thepolyglotdeveloper.com/2016/02/upload-files-to-node-js-using-angular-2/

Gibt es eine bessere Lösung, dies zu erreichen? Eine Lösung, die näher an meinem Code ist, weil ich maximale Standardisierung möchte? Zum Beispiel mit dem $ http Angular Service, den ich bereits verwende?

Danke!

Antwort

2

Datei-Upload in angular2,

In der Tat, die Http Klasse nicht, dass im Moment unterstützen.

Sie müssen das zugrunde liegende XHR Objekt nutzen, das zu tun:

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); 
    }); 
    } 
} 

dieses plunkr Siehe für weitere Informationen: https://plnkr.co/edit/ozZqbxIorjQW15BrDFrg?p=info.

a Es gibt ein Problem und ein PR anhängig dies im Angular Repo zu:

Antwort nahm from here

+0

Antwort ist genau ähnlich wie [dieser antwort] (http://stackoverflow.com/a/35985489/2435473) (decto jedes Wort wird kopiert, wie es ist), warum kennst du es nicht als ein duplicate .. anstatt es wieder zu schreiben –

+0

yeah es ist, weil ich denke, dass Frage etwas anderes von dieser Frage ist, also das Posten als Antwort. –

+0

Dann, warum markieren Sie es nicht als Duplikat, wenn Sie dachten, es so .. oder einfach einen Antwort-Link zum Kommentar hinzufügen. –