如何使FileReader与Angular2一起使用?

时间:2015-06-14 14:01:19

标签: javascript angular

如何使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

5 个答案:

答案 0 :(得分:33)

首先,您必须在模板中的输入表单上指定更改事件的目标:

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

侦听器将文件从事件传递到readThis方法。阅读本文已经实现了它自己的FileReader。您也可以在函数中定义组件中的FileReader。

答案 1 :(得分:7)

来自@ 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> 

答案 2 :(得分:0)

添加

CREATE SEQUENCE pk_test
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 1
  CACHE 1;

CREATE TABLE test (
    id INT PRIMARY KEY CHECK (id=currval('pk_test')) DEFAULT nextval('pk_test'),
    num int not null
    );
ALTER SEQUENCE pk_test OWNED BY test.id;

-- Testing:
INSERT INTO test (num) VALUES (3) RETURNING id, num;
1,3 -- OK
2,3 -- OK

INSERT INTO test (id, num) values (30,3) RETURNING id, num;
/*
ERROR:  new row for relation "test" violates check constraint "test_id_check"
DETAIL:  Failing row contains (30, 3).

********** Error **********

ERROR: new row for relation "test" violates check constraint "test_id_check"
SQL state: 23514
Detail: Failing row contains (30, 3).
*/

DROP TABLE test;

onLoad定义之后。

也许这可以帮到你,这是primeng

文件上传库的上传处理函数
fr.readAsText(event.files[0]);

答案 3 :(得分:0)

在这里参加聚会有点晚了。也可以通过创建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)
  }
}

答案 4 :(得分:0)

我将创建如下所示的方法

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])