Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload: list-type为picture-card时,beforeUpload返回false后,文件仍然为上传中的状态 #8020

Closed
elfman opened this issue Oct 26, 2017 · 20 comments

Comments

@elfman
Copy link
Contributor

elfman commented Oct 26, 2017

Version

2.13.7

Environment

Mac OSX 10.12.6, Chrome lastest

Reproduction link

https://codepen.io/HarlonLuo/pen/eGqrBb?editors=0010

Steps to reproduce

点击添加图片按钮,选择一个图片

What is expected?

在beforeUpload返回false后,直接显示图片缩略图

What is actually happening?

无缩略图,文字一直显示“文件上传中”

@ant-design-bot
Copy link
Contributor

It will be better to write your issue/comment in English, so more people can understand you.
And this means that more people can help you or benefit from your issue/comment.
See: #4897

@nikogu
Copy link
Contributor

nikogu commented Oct 26, 2017

参看文档:https://ant.design/components/upload-cn/#API

beforeUpload 返回 false 时停止上传。

@elfman
Copy link
Contributor Author

elfman commented Oct 26, 2017

是停止上传了,但是图片还是显示“文件上传中”,这不是bug吗?

@nikogu
Copy link
Contributor

nikogu commented Oct 26, 2017

Upload 组件确实没有做 local preview,但是可以自行控制 fileList,参考:

beforeUpload: (file) => {
  const reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onload = function(e) {
    // this is local preview
    file.url = e.target.result;
    this.setState(({ fileList }) => ({
      fileList: [...fileList, file],
     }));
  }
   return false;
}

如果你觉得需要内置或者有更好的实现,欢迎提交 pr

@elfman
Copy link
Contributor Author

elfman commented Oct 26, 2017

现在的Uploadtypepicture-card时,如果上传成功,显示的图片是local preview啊,查看元素可以看到imgsrc属性是data:image/xxxxxx,但用beforeUpload返回false不上传时这个图片并没有显示出来,应该是代码里没有将uploading这个状态修改回来

@nikogu
Copy link
Contributor

nikogu commented Oct 26, 2017

https://github.com/ant-design/ant-design/blob/master/components/upload/UploadList.tsx#L77

应该是这段,但是这个地方交互上不太好处理,因为显示缩略图容易让别人以为已经上传了。所以其实 uploading 这个状态也是有道理的

@elfman
Copy link
Contributor Author

elfman commented Oct 26, 2017

应该是再上两行的判断,beforeUploadfalse之后,为啥file.status === uploading仍然为true

@nikogu
Copy link
Contributor

nikogu commented Oct 26, 2017

这块交互还需要再讨论下 @afc163

@YuArtian
Copy link

我也遇到这个问题了,所以怎么不显示上传中,而是显示缩略图呢?

@Gavinchen92
Copy link

@nikogu 为什么beforeUpload返回了false, 还要触发一次onChange, 不是很明白. 我需要onChange来控制图片队列的, 如删除上传失败的图片

@lehug
Copy link
Contributor

lehug commented Feb 1, 2018

我的期望是手动上传多张照片,点击上传只是选择照片执行预览,然后再通过一个特定的按钮,触发批量上传到后台,使得调用后台频率减少,数据有效性提高

我这同时还有一个bug,picture-card类型的,图片已经上传,但是还是显示上传中,代码与官方示例相同,偶现,一般上传第二个照片就正常了。应该是onChange setState时那个file的status还是loading?

@luyimei
Copy link

luyimei commented Apr 2, 2018

i think it's a bug.
don't use return false , use Promise and reject will avoid the unwanted loading file.
like this:

     const beforeUpload = (file) => {
      return new Promise((resolve, reject) => {
        if(file.type !== 'image/jpeg' && file.type !== 'image/png') {
          message.error('file type required jpg or png');
          reject(file);
        }else {
          resolve(file);
        }
      });
    };

@CodePlayer7
Copy link
Contributor

@luyimei was right, return false still fires onChange while promise not

@littleLane
Copy link
Contributor

littleLane commented Apr 14, 2018

@luyimei I am not completely agree this pr!
There is a reason that when the selected file verification fails,
some people want to show original button instead of thumbnail to re-select other photo!
And displaying a thumbnail will make the user feel that the picture was uploaded successfully!
Maybe, this should be configurable!
This is my idea!

@iiiok
Copy link

iiiok commented May 7, 2018

luyimei's solution solved my issue, filtering out the "file oversize" file in beforeUpload().
but for the file.type filtering, I guess we can just use "accept: fileType", a build-in option.

@jYh1014
Copy link

jYh1014 commented May 9, 2018

我也发现了,在beforeUpload钩子函数里面,return false并不能阻止文件的上传,但是可以用promise里面的reject(file)来阻止

@Gavinchen92
Copy link

@jYh1014 我也是这么处理的

@kennylbj
Copy link

+1

@mattcarlotta
Copy link

mattcarlotta commented Jul 31, 2018

This component is probably one of the most finicky components I've ever had to work with. I wanted to validate the file without uploading to my API, and only after passing validation, can a user click an Upload button to initiate the upload. When using the @luyimei solution, the upload box border becomes red (as if it failed to upload and/or contains wrong file specifications) and ultimately looks incorrect. So... I had to basically write something like so:

Example (red outline):
https://codesandbox.io/s/wo15m3qzz7

Working example:
https://codesandbox.io/s/0qy8wl64pl

        beforeUpload = (file, fileList) => (
	  new Promise((resolve, reject) => {
	    this.validateFile(file).then(imageUrl => {
	      this.setState({ imageUrl });
	      resolve(file);
	    })
	    .catch(({height, width}) => {
	      message.error(`Only 10MB@256px/256px (image/jpg,png,bmp,gif) files are accepted! Instead, received a: ${(file.size/1024000).toFixed(2)}MB@${height ? height : '0'}px/${width ? width : 0}px (${file.type})!`, 
                10
              );
	      reject(file);
            })
	  })
	)

	readFile = (file, resolve, reject) => {
	  const reader = new FileReader();
	  reader.addEventListener('load', () => {
	    let image = new Image();
	      image.src = reader.result;
	      image.onload = () => {
	       (image.height <= 256 || image.width <= 256)
	         ? resolve(reader.result)
		 : reject({ height: image.height, width:image.width})
	      }
	  });
	  reader.readAsDataURL(file);
	}

	validateFile = (file) => (
	  new Promise((resolve, reject) => {
	    const isJPG = file.type === 'image/jpeg';
	    const isPNG = file.type === 'image/png';
	    const isGIF = file.type === 'image/gif';
	    const isBMP = file.type === 'image/bmp';
	    const isLt10MB = file.size / 10240000 <= 1;

	    ((isJPG || isPNG || isGIF || isBMP) && isLt10MB)
	      ? this.readFile(file, resolve, reject)
	      :	reject(null)
	  })
	)

	handleFileChange = ({ file, fileList }) => file.status = 'done';

@afc163
Copy link
Member

afc163 commented Apr 9, 2019

#15561 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests