Как заставить FileReader работать с Angular2?
Как заставить FileReader работать с Angular2!!
При чтении файла с клиентской стороны Angular2 и Typescript,
Я пытаюсь использовать FileReader таким образом:
var fileReader = new FileReader();
fileReader.onload = function(e) {
console.log("run fileReader.onload");
// ......
}
Но это вообще не работает, эта функция "fileReader.onload" никогда не будет вызвана.
На самом деле нужно решение для чтения файлов, пожалуйста, помогите.
Благодаря
Проверьте это из интерактивной среды IDE:
Предварительный просмотр:
https://angular2-butaixianran.c9.io/src/index.html
Редактор:
https://ide.c9.io/butaixianran/angular2
Ответы
Ответ 1
Сначала вы должны указать цель события изменения в форме ввода в шаблоне:
@View({
template:`
<div>
Select file:
<input type="file" (change)="changeListener($event)">
</div>
`
})
Как вы можете видеть, я привязал метод changeListener()
к событию (change)
. Моя реализация класса:
changeListener($event) : void {
this.readThis($event.target);
}
readThis(inputValue: any) : void {
var file:File = inputValue.files[0];
var myReader:FileReader = new FileReader();
myReader.onloadend = function(e){
// you can perform an action with readed data here
console.log(myReader.result);
}
myReader.readAsText(file);
}
Listener передает файл из события в метод readThis
. Прочтите это, внедрив собственный FileReader
. Вы также можете определить FileReader в компоненте вместо функции.
Ответ 2
Ответ от @haz111 уже работает, но на всякий случай вы хотите сделать файловый читатель повторно используемым компонентом, вы могли бы использовать это или лучше: улучшите это:
inputfilereader.ts
import {Component, ElementRef, EventEmitter} from 'angular2/angular2';
@Component({
selector: 'filereader',
templateUrl: './commons/inputfilereader/filereader.html',
styleUrls: ['./commons/inputfilereader/filereader.css'],
providers: [ElementRef],
events : ['complete']
})
export class InputFileReader {
complete :EventEmitter = new EventEmitter();
constructor(public elementRef: ElementRef) {
}
resultSet:any; // dont need it
changeListener($event: any) {
var self = this;
var file:File = $event.target.files[0];
var myReader:FileReader = new FileReader();
myReader.readAsText(file);
var resultSet = [];
myReader.onloadend = function(e){
// you can perform an action with data read here
// as an example i am just splitting strings by spaces
var columns = myReader.result.split(/\r\n|\r|\n/g);
for (var i = 0; i < columns.length; i++) {
resultSet.push(columns[i].split(' '));
}
self.resultSet=resultSet; // probably dont need to do this atall
self.complete.next(self.resultSet); // pass along the data which would be used by the parent component
};
}
}
filereader.html
<input type="file" (change)="changeListener($event)" />
Использование в других файлах
anotherfile позволяет сказать dfs.ts
import {Component, ElementRef} from 'angular2/angular2';
import {InputFileReader} from '../../commons/inputfilereader/inputfilereader';
@Component({
selector: 'dfs',
templateUrl: './components/dfs/dfs.html',
styleUrls: ['./components/dfs/dfs.css'],
providers: [ElementRef],
directives:[InputFileReader]
})
export class DfsCmp {
constructor(public eleRef :ElementRef) {}
callSomeFunc(data):void {
console.log("I am being called with ", data);
}
}
dfs.html
<filereader (complete)="callSomeFunc($event)"></filereader>
Ответ 3
Просто добавьте
fr.readAsText(event.files[0]);
После определения onLoad.
Возможно, это может вам помочь, это моя функция обработчика загрузки для библиотеки загрузки файлов primeng
archivoUploadHandler(event) {
let contenido;
let fr = new FileReader();
fr.onload = (e) => {
contenido = fr.result;
console.log(contenido);
};
fr.readAsText(event.files[0]);
}
Ответ 4
немного опоздал на вечеринку здесь. Это также можно сделать, создав FileReader как сервис. Это поможет модульным тестам и отделит FileReader от компонента, который его использует.
вы можете создать токен следующим образом:
export const FileReaderService = new InjectionToken<FileReader>('FileReader', {
factory: () => new FileReader(),
});
И тогда вы можете использовать его следующим образом: (Я считаю, что его можно использовать как обычный сервис. Я еще не тестировал его. Но способ, которым я здесь показываю, работает просто отлично)
class MyService { // this could be a component too
constructor(@Inject(FileReaderService) private reader: FileReader) {}
readFile() {
const file = // the file you want to read
this.reader.onload = // whateever you need
this.reader.readAsDataURL(file)
}
}
Ответ 5
Я хотел бы создать метод, как показано ниже
readFileContent(file: File): Promise<string | ArrayBuffer> {
return new Promise<string | ArrayBuffer>((resolve, reject) => {
const myReader: FileReader = new FileReader();
myReader.onloadend = (e) => {
resolve(myReader.result);
};
myReader.onerror = (e) => {
reject(e);
};
myReader.readAsText(file);
});
}
и называть это как
const content = await this.readFileContent(inputValue.files[0])