Caricamento file angular 2 da tipo di input = file

Usando angular 2 beta, e non riesco a ottenere input di tipo file per funzionare.

Usando la diagnostica posso vedere il binding a due vie per altri type come il testo.

 
{{diagnostic}}

Nel mio file typescript ho a disposizione la linea diagnostica:

 get diagnostic() { return JSON.stringify(this.model); } 

Potrebbe essere che è il problema di non essere JSON? Il valore è null .

Non riesco davvero a verificare il valore dell’input; in qualche modo anche se il testo accanto agli aggiornamenti “Scegli file …”, non riesco a vedere le differenze nel DOM.

Penso che non sia supportato. Se si osserva questa direttiva DefaultValueAccessor (consultare https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/directives/default_value_accessor.ts#L23 ). Vedrai che il valore utilizzato per aggiornare l’elemento associato è $event.target.value .

Questo non si applica nel caso di input con file tipo poiché l’object file può essere raggiunto $event.srcElement.files .

Per maggiori dettagli, puoi dare un’occhiata a questo plunkr: https://plnkr.co/edit/ozZqbxIorjQW15BrDFrg?p=info :

 @Component({ selector: 'my-app', template: ` 
`, providers: [ UploadService ] }) export class AppComponent { onChange(event) { var files = event.srcElement.files; console.log(files); } }
 @Component({ selector: 'my-app', template: ` 
`, providers: [ UploadService ] }) export class AppComponent { file: File; onChange(event: EventTarget) { let eventObj: MSInputMethodContext = event; let target: HTMLInputElement = eventObj.target; let files: FileList = target.files; this.file = files[0]; console.log(this.file); } doAnythingWithFile() { } }

C’è un modo leggermente migliore per accedere ai file allegati. È ansible utilizzare la variabile di riferimento del modello per ottenere un’istanza dell’elemento di input.

Ecco un esempio basato sulla prima risposta:

 @Component({ selector: 'my-app', template: ` 
`, providers: [ UploadService ] }) export class AppComponent { onChange(files) { console.log(files); } }

Ecco un’app di esempio per dimostrarlo in azione.

Le variabili di riferimento del modello potrebbero essere utili, ad esempio è ansible accedervi tramite @ViewChild direttamente nel controller.

Un altro modo utilizzando la variabile di riferimento del modello e ViewChild, come proposto da Frelseren:

 import { ViewChild } from '@angular/core'; @Component({ selector: 'my-app', template: ` 
` }) export class AppComponent { @ViewChild("fileInput") fileInputVariable: any; randomMethod() { const files = this.fileInputVariable.nativeElement.files; console.log(files); } }

Vedi anche https://stackoverflow.com/a/40165524/4361955

Prova questa piccola lib, funziona con Angular 5.0.0

Esempio di avvio rapido con ng2-file-upload 1.3.0:

L’utente fa clic sul pulsante personalizzato, che triggers la finestra di dialogo di caricamento dal tipo di input nascosto = “file”, il caricamento inizia automaticamente dopo aver selezionato un singolo file.

app.module.ts:

 import {FileUploadModule} from "ng2-file-upload"; 

your.component.html:

 ...   ... 

your.component.ts:

 import {FileUploader} from 'ng2-file-upload'; ... uploader: FileUploader; ... constructor() { this.uploader = new FileUploader({url: "/your-api/some-endpoint"}); this.uploader.onErrorItem = item => { console.error("Failed to upload"); this.clearUploadField(); }; this.uploader.onCompleteItem = (item, response) => { console.info("Successfully uploaded"); this.clearUploadField(); // (Optional) Parsing of response let responseObject = JSON.parse(response) as MyCustomClass; }; // Asks uploader to start upload file automatically after selecting file this.uploader.onAfterAddingFile = fileItem => this.uploader.uploadAll(); } private clearUploadField(): void { (window.document.getElementById('myFileInputField')) .value = ""; } 

La lib alternativa funziona in Angular 4.2.4, ma richiede alcuni accorgimenti da adottare per Angular 5.0.0

Se hai una forma complessa con più file e altri input, ecco una soluzione che funziona bene con ngModel .

Consiste di un componente di input di file che include un semplice input di file e implementa l’interfaccia ControlValueAccessor per renderlo consumabile da ngModel . Il componente espone l’object FileList su ngModel .

Questa soluzione è basata su questo articolo.

Il componente è usato in questo modo:

   

Ecco il codice del componente:

 import { Component, Input, forwardRef } from '@angular/core'; import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; const noop = () => { }; export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => FileInputComponent), multi: true }; @Component({ selector: 'file-input', templateUrl: './file-input.component.html', providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR] }) export class FileInputComponent { @Input() public name:string; @Input() public inputId:string; private innerValue:any; constructor() { } get value(): FileList { return this.innerValue; }; private onTouchedCallback: () => void = noop; private onChangeCallback: (_: FileList) => void = noop; set value(v: FileList) { if (v !== this.innerValue) { this.innerValue = v; this.onChangeCallback(v); } } onBlur() { this.onTouchedCallback(); } writeValue(value: FileList) { if (value !== this.innerValue) { this.innerValue = value; } } registerOnChange(fn: any) { this.onChangeCallback = fn; } registerOnTouched(fn: any) { this.onTouchedCallback = fn; } changeFile(event) { this.value = event.target.files; } } 

Ed ecco il modello di componente: