file-upload input angular

file upload - Carga de archivos desde<input type="file">



upload file angular 4 (7)

Usando angular 2 beta, parece que no puedo obtener un <input type="file"> para trabajar.

Utilizando el diagnóstico, puedo ver el enlace bidireccional para otros type , como el text .

<form> {{diagnostic}} <div class="form-group"> <label for="fileupload">Upload</label> <input type="file" class="form-control" [(ngModel)]="model.fileupload"> </div> </form>

En mi archivo TypeScript, tengo la siguiente línea de diagnóstico:

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

¿Podría ser que se trata de no ser JSON? El valor es null .

Realmente no puedo verificar el valor de la input . Aunque el texto junto a "Elegir archivo ..." se actualiza, no puedo ver diferencias en el DOM por alguna razón.


Creo que no es compatible. Si echa un vistazo a esta directiva DefaultValueAccessor (consulte https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/directives/default_value_accessor.ts#L23 ). Verá que el valor utilizado para actualizar el elemento enlazado es $event.target.value .

Esto no se aplica en el caso de entradas con tipo de file ya que se puede alcanzar el objeto de archivo $event.srcElement.files en $event.srcElement.files lugar.

Para obtener más detalles, puede echar un vistazo a este plunkr: https://plnkr.co/edit/ozZqbxIorjQW15BrDFrg?p=info :

@Component({ selector: ''my-app'', template: ` <div> <input type="file" (change)="onChange($event)"/> </div> `, providers: [ UploadService ] }) export class AppComponent { onChange(event) { var files = event.srcElement.files; console.log(files); } }


Hay una forma ligeramente mejor de acceder a los archivos adjuntos. Puede usar la variable de referencia de plantilla para obtener una instancia del elemento de entrada.

Aquí hay un ejemplo basado en la primera respuesta:

@Component({ selector: ''my-app'', template: ` <div> <input type="file" #file (change)="onChange(file.files)"/> </div> `, providers: [ UploadService ] }) export class AppComponent { onChange(files) { console.log(files); } }

Aquí hay una aplicación de ejemplo para demostrar esto en acción.

Las variables de referencia de plantilla pueden ser útiles, por ejemplo, puede acceder a ellas a través de @ViewChild directamente en el controlador.


Otra forma de usar la variable de referencia de plantilla y ViewChild, según lo propuesto por Frelseren:

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

Consulte también https://.com/a/40165524/4361955


Prueba esta pequeña lib, funciona con Angular 5.0.0

Ejemplo de inicio rápido con ng2-file-upload 1.3.0:

El usuario hace clic en el botón personalizado, que activa el diálogo de carga desde el tipo de entrada oculto = "archivo", la carga se inicia automáticamente después de seleccionar un solo archivo.

app.module.ts:

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

your.component.html:

... <button mat-button onclick="document.getElementById(''myFileInputField'').click()" > Select and upload file </button> <input type="file" id="myFileInputField" ng2FileSelect [uploader]="uploader" style="display:none"> ...

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 { (<HTMLInputElement>window.document.getElementById(''myFileInputField'')) .value = ""; }

Lib alternativo, funciona en Angular 4.2.4, pero requiere algunas soluciones alternativas para adoptar Angular 5.0.0


Si tiene una forma compleja con múltiples archivos y otras entradas, aquí hay una solución que funciona bien con ngModel .

Consiste en un componente de entrada de archivo que envuelve una entrada de archivo simple e implementa la interfaz ControlValueAccessor para que sea consumible por ngModel . El componente expone el objeto ngModel a ngModel .

Esta solución se basa en this artículo.

El componente se usa así:

<file-input name="file" inputId="file" [(ngModel)]="user.photo"></file-input> <label for="file"> Select file </label>

Aquí está el código 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; } }

Y aquí está la plantilla del componente:

<input type="file" name="{{ name }}" id="{{ inputId }}" multiple="multiple" (change)="changeFile($event)"/>


solo intenta (onclick)="this.value = null"

en su página html agregue el método onclick para eliminar el valor anterior para que el usuario pueda seleccionar el mismo archivo nuevamente.


@Component({ selector: ''my-app'', template: ` <div> <input name="file" type="file" (change)="onChange($event)"/> </div> `, providers: [ UploadService ] }) export class AppComponent { 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); } doAnythingWithFile() { } }