2016-09-01 44 views
9

Chcę zakodować przesłane pliki na base64, aby móc je przekazać do żądania. Problem polega na tym, że używam Angular 2 with Typescript i nie mogłem znaleźć żadnych informacji, jak to zrobić. Zauważyłem, że w JavaScript można to zrobić za pomocą canvas, ale nie wiem, jak mogę zaimplementować kod w maszynopisie.Angular 2 koduje obraz do base64

<input type="file" class="form-control" accept="image/*" multiple 
    [(ngModel)]="spot.images" name="images"> 
+0

jakiegoś powodu nie używasz FileReader.readAsDataURL()? –

+0

jakieś rozwiązanie? Też potrzebuję tego –

Odpowiedz

22

więc znaleźć rozwiązanie:

compontent.ts

changeListener($event) : void { 
    this.readThis($event.target); 
} 

readThis(inputValue: any): void { 
    var file:File = inputValue.files[0]; 
    var myReader:FileReader = new FileReader(); 

    myReader.onloadend = (e) => { 
    this.image = myReader.result; 
    } 
    myReader.readAsDataURL(file); 
} 

component.html

<input type="file" accept="image/*" (change)="changeListener($event)"> 
+0

To działa idealnie. Byłem nawet w stanie zawrzeć go w komponencie, który wiąże się z ngmodel, aby użyć go jako formantu formularza. Zobacz moją odpowiedź, jeśli jesteś zainteresowany. – Josh

+0

Dzień dobry! A może w wielu plikach? –

0

Można utworzyć klasy otoki dla klasy FileReader do zwracania observable.Subscribe dla niego i na sukces użyć .target uzyskać base64 dla rób co chcesz.

import {ReplaySubject} from "rxjs/ReplaySubject"; 
import {Observable} from "rxjs/Observable"; 

export class ObservableFileReader { 

    constructor(){} 

    public readFile(fileToRead: File): Observable<MSBaseReader>{ 
    let base64Observable = new ReplaySubject<MSBaseReader>(1); 

    let fileReader = new FileReader(); 
    fileReader.onload = event => { 
     base64Observable.next(fileReader.result); 
    }; 
    fileReader.readAsDataURL(fileToRead); 

    return base64Observable; 
    } 
} 
+0

Czy możesz dodać fragment kodu tego? Nie wpadłem na pomysł tutaj – Mantas

5

Oto powyższa odpowiedź zawinięta w składnik wielokrotnego użytku, który wiąże się z ngmodel.

import { NgModule, Component, Input, Output, ElementRef, forwardRef } from '@angular/core'; 
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; 
import { FormsModule } from "@angular/forms"; 

@Component({ 
    selector: 'file-upload', 
    template: `<input *ngIf="showFileNameInput" id="uploadFile" class="upload-file form-control" placeholder="Choose File" [(ngModel)]="selectedFileName" disabled="disabled" /> 
       <div class="fileUpload btn btn-primary"> 
        <span>{{uploadButtonText}}</span> 
        <input type="file" class="upload" accept="*" (change)="changeListener($event)"> 
       </div>`, 
    providers: [ 
     { 
      provide: NG_VALUE_ACCESSOR, 
      useExisting: forwardRef(() => FileUploadComponent), 
      multi: true 
     } 
    ] 
}) 
export class FileUploadComponent implements ControlValueAccessor { 
    selectedFileName: string = null; 
    @Input() showFileNameInput: boolean; 
    @Input() uploadButtonText: string; 

    writeValue(value: any) { 
     //Handle write value 
    } 
    propagateChange = (_: any) => { }; 
    registerOnChange(fn) { 
     this.propagateChange = fn; 
    } 
    registerOnTouched() { } 

    changeListener($event): void { 
     // debugger; // uncomment this for debugging purposes 
     this.readThis($event.target); 
    } 
    readThis(inputValue: any): void { 
     // debugger; // uncomment this for debugging purposes 
     var file: File = inputValue.files[0]; 
     var myReader: FileReader = new FileReader(); 

     myReader.onloadend = (e) => { 
      this.propagateChange(myReader.result); 
      this.selectedFileName = file.name; 
     } 
     myReader.readAsDataURL(file); 
    } 
} 

@NgModule({ 
    declarations: [ 
     FileUploadComponent 
    ], 
    imports: [FormsModule], 
    exports: [ 
     FileUploadComponent 
    ] 
}) 
export class FileUploadModule { } 

które mogą być używane jak

<file-upload [showFileNameInput]="true" allowedTypes="image/*" uploadButtonText="Upload File" [(ngModel)]="someProperty"></file-upload> 

także niektóre css, który pomógł to wtopić bootstrap na mojej stronie

/********************************/ 
/* File Upload */ 
.fileUpload { 
    position: relative; 
    overflow: hidden; 
} 

.fileUpload input.upload { 
    position: absolute; 
    top: 0; 
    right: 0; 
    margin: 0; 
    padding: 0; 
    font-size: 20px; 
    cursor: pointer; 
    opacity: 0; 
    filter: alpha(opacity=0); 
} 

.upload-file { 
    &.form-control { 
     width: auto; 
     display: inherit; 
    } 
} 
+0

jak możesz przekazać to do żądania? Jaka jest tutaj wartość base64? –

+0

@MixAustria Wartość base64 jest wyprowadzana na wszystko, co jest związane z ngModel lub formControl komponentu. Możesz go użyć w ten sposób: Łańcuch podstawowy 64 będzie w "someProperty" na twoim komponencie – Josh

+0

czy masz na myśli, że 'someProperty' jest zmienną wewnątrz komponentu? Przepraszam, jestem naprawdę nowy. –