【问题标题】:Getting JSON data from a file in NGRX / Angular 7 app从 NGRX / Angular 7 应用程序中的文件获取 JSON 数据
【发布时间】:2020-01-06 21:19:25
【问题描述】:

我正在使用现有的 NgRx/Redux 应用程序和新的应用程序(第一个应用程序)。我在 SO 上使用了以前的答案,但无法将其添加到 NgRx 效果中。

我的组件中有以下 HTML/Angular:

<div class="block">
  <label id="lbl">File </label>
  <input #fileInput type='file' (change)="_onChange($event)"/>
  <button class="btn btn-sm"  (click)="_uploadFile()">Upload The JSON File</button>
</div>

组件的 TS 文件有:

@Output() uploadFile = new EventEmitter();
    _uploadFile() {
    this.uploadFile.emit();
}

模块TS文件:

    uploadFile() {
        this.store.dispatch(new PageActions.UploadFile());
    }

动作文件:

export class UploadFile implements Action {
    readonly type = PageActionTypes.UploadFile;
    constructor(public payload: File) { }
}

效果文件:

@Effect()
uploadFile$: Observable<Action> = this.actions$.pipe(
    ofType(PACtions.PageActionTypes.UploadFile),
    map( action => action.payload ),
    // ...
);

从之前的 SO 回答中我看到了这一点:

export class AppComponent  {
  uploadedData: any;

  onChange(event) {
    const reader = new FileReader();
    reader.onload = e => {
      const raw = (<FileReader>e.target).result as string;
      const res = JSON.parse(raw);
      this.uploadedData = res;
    }
    reader.readAsText(event.target.files[0]);
  }

  uploadFile() {
    console.log(this.uploadedData);
    // this.store.dispatch(new PageActions.UploadFile(this.uploadedData));
  }

}

如何让 onChange($event) 和 uploadData 适合我的组件、效果和动作文件?我的组件只有 @Output ... 东西,工作发生在效果文件中。

更新

我有一个这样的下载状态文件。

在component.ts文件中:

@Output() downloadStateFile = new EventEmitter();
    _downloadStateFile() {
        this.downloadStateFile.emit();
    }

这工作正常,并被传递到效果文件来完成工作:

@Effect({ dispatch: false })
    downloadStateFile$ = this.actions$.pipe(
       ofType(TheActionTypes.DownloadState),
       withLatestFrom(this.store.select(fromSpace.getTheState)),
       tap(([empty, wspace]) => {
            console.log(JSON.stringify(wspace));

            // This code below was suggested from the following link:
            // https://stackoverflow.com/questions/42360665/angular2-to-export-download-json-file
            var jsonState = JSON.stringify(wspace);
            const clickElement = document.createElement('a');
            clickElement.setAttribute('href', "data:text/json;charset=UTF-8," + encodeURIComponent(jsonState));
            clickElement.setAttribute('download', "state-file.json");
            clickElement.style.display = 'none';
            document.body.appendChild(clickElement);
            clickElement.click(); // simulate click
            document.body.removeChild(clickElement);
       })
   );

我需要uploadState 来做类似的事情,但要获取文件中的状态并将状态上传到reducer。但是首先它需要按照项目来做所有的效果中的FileReader。

更新 #2

我只有一个组件,因为在您的 mock 中创建的 FileUploader 组件在我的中不存在,所以我只有:

<div class="block">
  <label id="lbl">File </label>
  <input #fileInput type='file' (change)="_onChange($event)"/>
  <button class="btn btn-sm"  (click)="_uploadFile()">Upload The JSON File</button>
</div>

根据您提供的内容,我在上面的 html 的 .ts 文件中有这个:

@Output() onChange = new EventEmitter();
    _onChange(event) {
        this.onChange.emit(event.target.files[0]);
    }

在您的代码中,readFile 中有第二层,它传入 inputFile 有效负载。如何将其添加到我的上述更新中?感谢您的帮助。

【问题讨论】:

  • 你能发布你的reducer文件吗?
  • 我怎么去reducer是问题所在?一旦我从效果中恢复了动作,我会将它发送到减速器
  • (如果我理解你的问题的话)你需要在效果后使用exhaustMap。然后根据成功或失败或文件上传后您想要执行的任何其他操作发送新操作。使用 dispatch false 处理新效果中的新操作。
  • @m.akari 你有这方面的例子吗?谢谢。

标签: angular typescript angular7 ngrx ngrx-effects


【解决方案1】:

以下是组织满足上述要求的代码的一种方法。

  • file-upload 功能分离到一个独立的组件。本质上,FileUploader 组件将是一个仅通过 EventEmitter 进行通信的哑组件。
  • 父组件挂钩到upload 事件并调度适当的操作,将从FileUploader 接收的数据作为有效负载传递。
  • store reducer 根据业务逻辑设置适当的状态。同时,effect 可以连接到相同的(模拟“API 调用”)

查看this 的模拟实现。

编辑

根据在效果中使用FileReader 的新要求,已修改模拟实现以适应此更改。

编辑 2

基于不使用store而仅使用效果的新要求,可以引入另一个Injectable,由Subject支持,然后提供一种跨componenteffects进行通信的方式.示例代码在模拟实现中更新。

【讨论】:

  • 我需要它不仅仅是有角度的,而是 NgRx!它需要有副作用和减少剂。您提供的模拟没有。
  • 它拥有一切。 app.state.ts 有减速器,app.effects.ts 有效果,app.component.ts 有 NGRX 绑定
  • 为了这个现有的项目,我希望/需要在效果中有 ofChange、uploadData(?) 和 uploadFile。可以这样做吗?这就是我要找的。所以我想要效果中的 FileReader。这是项目实现事物的方式(不是我)。动作只接受输入并传递输出。
  • 查看我上面的 downloadState 更新,了解我们需要如何使用这个项目完成模式。
  • 谢谢。越来越近。我在上面的问题中添加了有关 inputFile 有效负载的另一个详细信息。学到了很多东西。谢谢。
猜你喜欢
  • 1970-01-01
  • 2017-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-16
  • 2018-06-19
  • 1970-01-01
  • 2019-04-27
相关资源
最近更新 更多