简体   繁体   English

Flutter web 上传文件取消事件

[英]Flutter web upload file cancel event

I develop a web app in Flutter and I want to load a file from file system.我在 Flutter 中开发了一个 web 应用程序,我想从文件系统加载文件。 In order to do that I use the following code:为此,我使用以下代码:

static Future<Uint8List> chooseImage(dynamic parent, dynamic provider) async {
  Uint8List uploadedImage;
  final completer = Completer<List<String>>();
  InputElement uploadInput = FileUploadInputElement();
  uploadInput.accept = 'image/*';
  uploadInput.click();
  uploadInput.addEventListener('change', (e) async {
    final files = uploadInput.files;
    Iterable<Future<String>> resultsFutures = files.map((file) {
      final reader = FileReader();
      reader.readAsDataUrl(file);
      reader.onError.listen((error) => completer.completeError(error));
      return reader.onLoad.first.then((_) async {
        String result = reader.result as String;
        uploadedImage = base64Decode(result.substring(22, result.length));
        return reader.result as String;
      });
    });

    final results = await Future.wait(resultsFutures);
    completer.complete(results);
  });
  document.body.append(uploadInput);
  final List<String> images = await completer.future;
  parent.setState(() {
    parent.pickedImage = uploadedImage;
  });
  uploadInput.remove();
  return uploadedImage;
}

In my app I need to handle the case when the user press the Cancel button in this pop-up:在我的应用程序中,当用户在此弹出窗口中按下取消按钮时,我需要处理这种情况: 在此处输入图像描述

I have added listener for: onFocus, onSuspen, onSubmit, onEnded, onAbort but none of these events are triggered when that cancel button is pressed.我添加了以下监听器:onFocus、onSuspen、onSubmit、onEnded、onAbort,但是当按下取消按钮时,这些事件都不会被触发。

How can I handle the pop-up cancelation?如何处理弹出取消?

I've already answered to a similar question here 我已经在这里回答了类似的问题

You can already find a way to manage this kind of event in the web implementation of the package file_picker .您已经可以在 package file_picker的 web 实现中找到管理此类事件的方法。

Because depending of the browser you are using the cancel event might be managed differently the most generic solution would be to rely on a listener on the focus event from the window so when you will lose the focus on your file picker window without any data loaded, it will complete your future with a null value.因为根据您使用的浏览器的不同,取消事件的管理方式可能不同,所以最通用的解决方案是依赖 window 中的focus事件的侦听器,因此当您在没有加载任何数据的情况下失去对文件选择器 window 的关注时,它将以null值完成您的未来。

Code Sample代码示例

import 'dart:html' as html;
import 'dart:async';

Future<html.File?> pickFile(String type) async {
  final completer = Completer<List<html.File>?>();
  final input = html.FileUploadInputElement() as html.InputElement;
  input.accept = '$type/*';

  var changeEventTriggered = false;
  void changeEventListener(html.Event e) {
    if (changeEventTriggered) return;
    changeEventTriggered = true;

    final files = input.files!;
    final resultFuture = files.map<Future<html.File>>((file) async {
      final reader = html.FileReader();
      reader.readAsDataUrl(file);
      reader.onError.listen(completer.completeError);
      return file;
    });
    Future.wait(resultFuture).then((results) => completer.complete(results));
  }

  void cancelledEventListener(html.Event e) {
    html.window.removeEventListener('focus', cancelledEventListener);

    // This listener is called before the input changed event,
    // and the `uploadInput.files` value is still null
    // Wait for results from js to dart
    Future.delayed(Duration(milliseconds: 500)).then((value) {
      if (!changeEventTriggered) {
        changeEventTriggered = true;
        completer.complete(null);
      }
    });
  }

  input.onChange.listen(changeEventListener);
  input.addEventListener('change', changeEventListener);

  // Listen focus event for cancelled
  html.window.addEventListener('focus', cancelledEventListener);

  input.click();

  final results = await completer.future;
  if (results == null || results.isEmpty) return null;
  return results.first;
}

Sources来源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM