首页 > 解决方案 > 在下载 blob 文件之前显示加载消息

问题描述

提交账单表格后,我将账单打印为 pdf 文件。正在下载 blob 文件的服务如下。

export default [createLogic({
  type: reportTypes.REPORT,
  latest: true,
  debounce: 2000,

  process({ MockHTTPClient, getState, action }, dispatch, done) {


    dispatch(reportActions.queryStart())
    let HTTPClient;
    if (MockHTTPClient) {
      HTTPClient = MockHTTPClient;
    } else {
      HTTPClient = API;
    }

    HTTPClient.Post(endPoints.REPORTS_BILL, action.payload.reportOptions)
      .then(
        (resp) => {
          return resp.data
        })
      .then((data) => {
        dispatch(reportActions.getReportSuccess(data));

        var link = document.createElement('a');
        link.href = `data:application/octet-stream;base64,${data}`;
        var today = new Date();
        var date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
        var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds() + ":" + today.getMilliseconds();
        var dateTime = date + ' ' + time;
        var fileName = dateTime + "billing.pdf";
        link.download = fileName;
        link.click();

        var base64str = data;
        var binary = atob(base64str.replace(/\s/g, ''));
        var len = binary.length;
        var buffer = new ArrayBuffer(len);
        var view = new Uint8Array(buffer);
        for (var i = 0; i < len; i++) {
          view[i] = binary.charCodeAt(i);
        }
        var blob = new Blob([view], { type: "application/pdf" });
        var url = URL.createObjectURL(blob);
        window.open(url);
        dispatch(reportActions.getReportSuccess(data))

      })
      .then(() => dispatch(reportActions.queryEnd()))
      .catch(err => {
        dispatch(reportActions.getReportFailed());
        var errorMessage = "Failed to get prductivity data.";
        if (err && err.code == "ECONNABORTED") {
          errorMessage = "Please check your internet connection.";
        }


        dispatch(
          reportActions.getReportFailed({
            title: "Error!",
            message: errorMessage
          })
        );
      })
      .then(() => done()); 
  }
})
]

在计费组件中,以下是我调用服务的方法。

printBill = () => {
    debugger;
    var reportType = 1;
    var reportFiltersSet = {};
    if (this.billingOptions.length > 0) {
      this.billingOptions.map(v => {
        reportFiltersSet[v.name] = v.value;
      });
    }

    this.props.reportActions.queryStart();
    var reportType = 1; //Thiis need to be dynamic. use this => //this.state.reportType
    var reportFilters = this.state.billingOptions;

    if (
      reportFiltersSet.organization == undefined ||
      reportFiltersSet.department == undefined ||
      reportFiltersSet.division == undefined ||
      reportFiltersSet.billYear == undefined ||
      reportFiltersSet.billMonth == undefined
    ) {
      this.setState({
        reportContentNull: true,
        warning: "Error!",
        errorMessage:
          "Either department or division reqiured with organization , year and month",
        negative: true,
        hidden: false
      });




    this.props.reportActions.getReport({ reportOptions: reportFiltersSet });
    var reportDownloadType = this.state.reportType;
  };

当我毫无问题地提交表单时,我可以下载 blob 文件。但是从用户的角度来看,为了获得更好的用户体验,显示加载状态很重要。因此,任何人都可以帮助我在提交和加载 blob 文件期间显示加载消息吗?

标签: reactjsredux

解决方案


因此,想法是在调用发生时立即开始加载,HTTP并在收到响应时将其删除。

简单的方法是在状态中添加一个加载变量,并在渲染中检查该变量并显示微调器。

onClick = () => {
  this.setState({ loading: true }, () => {
    Axios.get('/sampelCall')
      .then(result => this.setState({
        loading: false,
        data: [...result.data],
      }));
  });
}


render() {
      const { data, loading } = this.state;
      return (
        <div>
          <button onClick={this.onClick}>
            Load Data
          </button>
          {loading ? <LoadingSpinner /> : <ResultsTable results={data} />}  // if loading in true will show Spinner
        </div>
      );
}

笔记:

您需要在所有情况下处理加载变量(成功/错误),否则 Spinner 将继续加载。


推荐阅读