Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wanjj_1210
ant-design
提交
b6ec8b9e
A
ant-design
项目概览
wanjj_1210
/
ant-design
与 Fork 源项目一致
从无法访问的项目Fork
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
ant-design
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b6ec8b9e
编写于
9月 01, 2015
作者:
Y
yiminghe
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #226 from ant-design/upload-filelist
重构 Upload API
上级
16004a4b
b4a3d3e4
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
243 addition
and
157 deletion
+243
-157
CHANGELOG.md
CHANGELOG.md
+10
-7
components/select/index.md
components/select/index.md
+1
-0
components/upload/demo/basic.md
components/upload/demo/basic.md
+7
-9
components/upload/demo/defaultFileList.md
components/upload/demo/defaultFileList.md
+40
-0
components/upload/demo/drag-simple.md
components/upload/demo/drag-simple.md
+2
-5
components/upload/demo/drag.md
components/upload/demo/drag.md
+2
-5
components/upload/demo/fileList.md
components/upload/demo/fileList.md
+72
-0
components/upload/demo/limit.md
components/upload/demo/limit.md
+0
-33
components/upload/getFileItem.js
components/upload/getFileItem.js
+1
-1
components/upload/index.jsx
components/upload/index.jsx
+66
-59
components/upload/index.md
components/upload/index.md
+30
-19
components/upload/uploadList.jsx
components/upload/uploadList.jsx
+12
-19
未找到文件。
CHANGELOG.md
浏览文件 @
b6ec8b9e
## 0.8.1 (not ready)
## 0.9.0 (not ready)
### Upload
**重构了 API 接口,不向下兼容**
,支持自定义的功能扩展。
*
新增
`onChange(file) {}`
接口,移出原来的
`onSuccess`
、
`onProgess`
、
`onError`
等接口。
*
新增
`fileList`
和
`defaultFileList`
属性,以满足更多的自定义功能,具体见演示。
*
设置 fileList 数组项的 url 属性可以作为链接展示在文件列表中方便下载。
### Table
...
...
@@ -7,12 +16,6 @@
*
修复远程模式 loading 失效的问题。
[
9b8abb2
](
https://github.com/ant-design/ant-design/commit/9b8abb219934c246970a84200818aa8f85974bdf
)
*
用
[
reqwest-without-xhr2
](
http://npmjs.com/reqwest-without-xhr2
)
代替了 reqwest,解决某些开发环境下 xhr2 依赖的问题。
### Upload
*
新增
`onRemove(file) {}`
接口,作为移除上传文件的回调。
*
新增
`urlResolver(res) {}`
接口,可以拿到请求回调数据里的远程文件地址,展示在文件列表中方便下载。
*
新增
`limit`
属性,用于限制文件上传列表的数量。
### Notification
*
修复不会自动消失的问题。
[
23fce55
](
https://github.com/ant-design/ant-design/commit/23fce559b0b2faf4e0b686a92dbcdd045727a464
)
...
...
components/select/index.md
浏览文件 @
b6ec8b9e
...
...
@@ -35,6 +35,7 @@
| allowClear | 显示清除按钮 | | false |
| placeholder | 选择框默认文字 | string | 无 |
| searchPlaceholder | 搜索框默认文字 | string | 无 |
| optionFilterProp | 输入项过滤对应的 option 属性 | string | value |
| combobox | 输入框自动提示模式 | | false |
| size | 选择框大小 | String | 无 |
...
...
components/upload/demo/basic.md
浏览文件 @
b6ec8b9e
...
...
@@ -10,13 +10,12 @@
var
Upload
=
antd
.
Upload
;
var
props
=
{
description
:
'
支持扩展名为: .rar .zip ...
'
,
action
:
'
/upload.do
'
,
data
:
{},
accept
:
''
,
uploadTip
:
''
,
onStart
(
file
){
console
.
log
(
file
.
uid
);
onChange
(
info
)
{
if
(
info
.
file
.
status
!==
'
uploading
'
)
{
console
.
log
(
info
.
file
);
console
.
log
(
info
.
fileList
);
}
}
};
...
...
@@ -25,7 +24,6 @@ React.render(
<
button
className
=
"ant-btn ant-btn-ghost"
>
<
i
className
=
"anticon anticon-upload"
></
i
>
点击上传
</
button
>
</
Upload
>,
document
.
getElementById
(
'
components-upload-demo-basic
'
)
);
</
Upload
>
,
document
.
getElementById
(
'
components-upload-demo-basic
'
));
````
components/upload/demo/defaultFileList.md
0 → 100644
浏览文件 @
b6ec8b9e
# 传入已上传的文件
-
order: 1
对已上传的文件进行编辑。
---
````
jsx
var
Upload
=
antd
.
Upload
;
var
props
=
{
action
:
'
/upload.do
'
,
onChange
(
info
)
{
if
(
info
.
file
.
status
!==
'
uploading
'
)
{
console
.
log
(
info
.
file
);
console
.
log
(
info
.
fileList
);
}
},
defaultFileList
:
[{
uid
:
-
1
,
name
:
'
xxx.png
'
,
status
:
'
done
'
,
url
:
'
http://www.baidu.com/xxx.png
'
},
{
uid
:
-
2
,
name
:
'
yyy.png
'
,
status
:
'
done
'
,
url
:
'
http://www.baidu.com/yyy.png
'
}]
};
React
.
render
(
<
Upload
{
...
props
}
>
<
button
className
=
"ant-btn ant-btn-ghost"
>
<
i
className
=
"anticon anticon-upload"
></
i
>
点击上传
</
button
>
</
Upload
>
,
document
.
getElementById
(
'
components-upload-demo-defaultfilelist
'
));
````
components/upload/demo/drag-simple.md
浏览文件 @
b6ec8b9e
# 拖拽上传
-
order:
2
-
order:
4
样式简单一些。
...
...
@@ -11,10 +11,7 @@ var Dragger = antd.Upload.Dragger;
var
props
=
{
name
:
'
file
'
,
action
:
'
/upload.do
'
,
data
:
{},
accept
:
''
,
uploadTip
:
''
action
:
'
/upload.do
'
};
React
.
render
(
...
...
components/upload/demo/drag.md
浏览文件 @
b6ec8b9e
# 拖拽上传
-
order:
1
-
order:
3
可以把文件拖入指定区域,完成上传,同样支持点击上传。
...
...
@@ -11,10 +11,7 @@ var Dragger = antd.Upload.Dragger;
var
props
=
{
name
:
'
file
'
,
action
:
'
/upload.do
'
,
data
:
{},
accept
:
'
i
'
,
uploadTip
:
''
action
:
'
/upload.do
'
};
React
.
render
(
...
...
components/upload/demo/fileList.md
0 → 100644
浏览文件 @
b6ec8b9e
# 完全控制的上传列表
-
order: 2
使用
`fileList`
对列表进行完全控制,可以实现各种自定义功能,以下演示三种情况:
1) 上传列表数量的限制。
2) 读取远程路径并显示链接。
3) 按照服务器返回信息筛选成功上传的文件。
---
````
jsx
var
Upload
=
antd
.
Upload
;
var
fileList
=
[{
uid
:
-
1
,
name
:
'
xxx.png
'
,
status
:
'
done
'
,
url
:
'
http://www.baidu.com/xxx.png
'
}];
var
MyUpload
=
React
.
createClass
({
getInitialState
()
{
return
{
fileList
:
fileList
};
},
handleChange
(
info
)
{
let
fileList
=
info
.
fileList
;
// 1. 上传列表数量的限制
// 只显示最近上传的一个,旧的会被新的顶掉
fileList
=
fileList
.
slice
(
-
2
);
// 2. 读取远程路径并显示链接
fileList
=
fileList
.
map
(
function
(
file
)
{
if
(
file
.
response
)
{
// 组件会将 file.url 作为链接进行展示
file
.
url
=
JSON
.
parse
(
file
.
response
).
url
;
}
return
file
;
});
// 3. 按照服务器返回信息筛选成功上传的文件
fileList
=
fileList
.
filter
(
function
(
file
)
{
if
(
file
.
response
)
{
return
JSON
.
parse
(
file
.
response
).
status
===
'
success
'
;
}
return
true
;
});
this
.
setState
({
fileList
:
fileList
});
},
render
()
{
var
props
=
{
action
:
'
/upload.do
'
,
onChange
:
this
.
handleChange
};
return
<
Upload
{
...
props
}
fileList
=
{
this
.
state
.
fileList
}
>
<
button
className
=
"ant-btn ant-btn-ghost"
>
<
i
className
=
"anticon anticon-upload"
></
i
>
点击上传
</
button
>
</
Upload
>;
}
});
React
.
render
(<
MyUpload
/>,
document
.
getElementById
(
'
components-upload-demo-filelist
'
));
````
components/upload/demo/limit.md
已删除
100644 → 0
浏览文件 @
16004a4b
# 文件列表限制
-
order: 3
`limit`
属性控制文件列表数的上限。如设为 1 时,表示只能上传一个文件,新文件会顶掉旧文件。
---
````
jsx
var
Upload
=
antd
.
Upload
;
var
props
=
{
description
:
'
支持扩展名为: .rar .zip ...
'
,
action
:
'
/upload.do
'
,
data
:
{},
accept
:
''
,
uploadTip
:
''
,
limit
:
1
,
onStart
(
file
){
console
.
log
(
file
.
uid
);
}
};
React
.
render
(
<
Upload
{
...
props
}
>
<
button
className
=
"ant-btn ant-btn-ghost"
>
<
i
className
=
"anticon anticon-upload"
></
i
>
点击上传,只支持一个文件
</
button
>
</
Upload
>,
document
.
getElementById
(
'
components-upload-demo-limit
'
)
);
````
components/upload/getFileItem.js
浏览文件 @
b6ec8b9e
...
...
@@ -2,7 +2,7 @@ export default function getFileItem(file, fileList) {
let
matchWay
=
(
!
file
.
uid
)
?
'
byName
'
:
'
byUid
'
;
let
target
=
fileList
.
filter
((
item
)
=>
{
if
(
matchWay
===
'
byName
'
)
{
return
item
.
filename
===
file
.
file
name
;
return
item
.
name
===
file
.
name
;
}
else
{
return
item
.
uid
===
file
.
uid
;
}
...
...
components/upload/index.jsx
浏览文件 @
b6ec8b9e
...
...
@@ -5,7 +5,6 @@ import Message from '../message';
import
UploadList
from
'
./uploadList
'
;
import
getFileItem
from
'
./getFileItem
'
;
const
prefixCls
=
'
ant-upload
'
;
let
fileIndex
=
0
;
function
noop
()
{
}
...
...
@@ -13,65 +12,78 @@ function noop() {
const
AntUpload
=
React
.
createClass
({
getInitialState
()
{
return
{
downloadList
:
[]
fileList
:
this
.
props
.
fileList
||
this
.
props
.
defaultFileList
||
[]
};
},
onStart
(
file
)
{
let
nextDownloadList
=
this
.
state
.
downloadList
;
nextDownloadList
.
push
({
index
:
fileIndex
++
,
uid
:
file
.
uid
||
''
,
filename
:
file
.
name
,
let
nextFileList
=
this
.
state
.
fileList
.
concat
();
file
.
status
=
'
uploading
'
;
nextFileList
.
push
(
file
);
this
.
onChange
({
file
:
file
,
status
:
'
downloading
'
fileList
:
nextFileList
});
if
(
nextDownloadList
.
length
===
this
.
props
.
limit
+
1
)
{
nextDownloadList
=
nextDownloadList
.
slice
(
1
);
}
this
.
setState
({
downloadList
:
nextDownloadList
});
this
.
props
.
onStart
(
file
);
},
removeFile
(
file
){
var
downloadList
=
this
.
state
.
downloadList
.
concat
();
let
targetItem
=
getFileItem
(
file
,
downloadList
);
var
index
=
downloadList
.
indexOf
(
targetItem
);
removeFile
(
file
)
{
file
.
status
=
'
removed
'
;
let
fileList
=
this
.
state
.
fileList
.
concat
();
let
targetItem
=
getFileItem
(
file
,
fileList
);
let
index
=
fileList
.
indexOf
(
targetItem
);
if
(
index
!==
-
1
)
{
downloadList
.
splice
(
index
,
1
);
fileList
.
splice
(
index
,
1
);
return
fileList
;
}
this
.
setState
({
downloadList
:
downloadList
});
return
null
;
},
onSuccess
(
re
t
,
file
)
{
var
res
=
this
.
props
.
onSuccess
(
ret
,
file
);
if
(
res
!==
false
)
{
var
downloadList
=
this
.
state
.
downloadList
.
concat
(
);
Message
.
success
(
file
.
name
+
'
上传完成
'
);
let
targetItem
=
getFileItem
(
file
,
downloadList
);
onSuccess
(
re
sponse
,
file
)
{
let
fileList
=
this
.
state
.
fileList
.
concat
(
);
Message
.
success
(
file
.
name
+
'
上传完成。
'
);
let
targetItem
=
getFileItem
(
file
,
fileList
);
// 之前已经删除
if
(
targetItem
)
{
targetItem
.
status
=
'
done
'
;
// 解析出文件上传后的远程地址
if
(
typeof
this
.
props
.
urlResolver
===
'
function
'
)
{
targetItem
.
url
=
this
.
props
.
urlResolver
(
ret
);
}
this
.
setState
({
downloadList
:
downloadList
targetItem
.
response
=
response
;
this
.
onChange
({
file
:
targetItem
,
fileList
:
this
.
state
.
fileList
});
}
else
{
this
.
removeFile
(
file
);
}
},
onProgress
(
e
,
file
)
{
this
.
props
.
onProgress
(
e
,
file
);
let
fileList
=
this
.
state
.
fileList
;
let
targetItem
=
getFileItem
(
file
,
fileList
);
if
(
targetItem
)
{
this
.
onChange
({
event
:
e
,
file
:
file
,
fileList
:
this
.
state
.
fileList
});
}
},
onError
(
err
,
responce
,
file
)
{
Message
.
error
(
file
.
name
+
'
上传失败
'
);
this
.
removeFile
(
file
);
this
.
props
.
onError
(
err
,
responce
,
file
);
onError
(
error
,
response
,
file
)
{
Message
.
error
(
file
.
name
+
'
上传失败。
'
);
file
.
error
=
error
;
file
.
response
=
response
;
this
.
handleRemove
(
file
);
},
handleRemove
(
file
)
{
let
fileList
=
this
.
removeFile
(
file
);
if
(
fileList
)
{
this
.
onChange
({
file
:
file
,
fileList
:
fileList
});
}
},
onRemove
(
file
){
this
.
props
.
onRemove
(
file
);
onChange
(
info
)
{
// 1. 有设置外部属性时不改变 fileList
// 2. 上传中状态(info.event)不改变 fileList
if
(
!
(
'
fileList
'
in
this
.
props
)
&&
!
info
.
event
)
{
this
.
setState
({
fileList
:
info
.
fileList
});
}
this
.
props
.
onChange
(
info
);
},
getDefaultProps
()
{
return
{
...
...
@@ -81,20 +93,16 @@ const AntUpload = React.createClass({
action
:
''
,
data
:
{},
accept
:
''
,
uploadTip
:
''
,
onStart
:
noop
,
onError
:
noop
,
onSuccess
:
noop
,
onProgress
:
noop
,
onRemove
:
noop
,
limit
:
Number
.
MAX_VALUE
,
urlResolver
:
function
(
ret
)
{
try
{
return
JSON
.
parse
(
ret
).
url
;
}
catch
(
e
)
{}
}
onChange
:
noop
,
};
},
componentWillReceiveProps
(
nextProps
)
{
if
(
'
fileList
'
in
nextProps
)
{
this
.
setState
({
fileList
:
nextProps
.
fileList
});
}
},
render
()
{
let
type
=
this
.
props
.
type
||
'
select
'
;
let
props
=
assign
({},
this
.
props
,
{
...
...
@@ -121,9 +129,8 @@ const AntUpload = React.createClass({
{
this
.
props
.
children
}
</
Upload
>
</
div
>
<
UploadList
items
=
{
this
.
state
.
downloadList
}
onRemove
=
{
this
.
onRemove
}
limit
=
{
props
.
limit
}
/>
<
UploadList
items
=
{
this
.
state
.
fileList
}
onRemove
=
{
this
.
handleRemove
}
/>
</
div
>
);
}
...
...
components/upload/index.md
浏览文件 @
b6ec8b9e
...
...
@@ -18,30 +18,41 @@
## API
| 参数
| 说明 | 类型 | 默认值
|
|-----------
|--------------------------------------------------------- |
---------- |-------|
| name | 可选参数, 上传的文件 | String | file
|
| 参数
| 说明 | 类型 | 默认值
|
|-----------
-|--------------------------------------------------------------| -
---------- |-------|
| name | 可选参数, 上传的文件 | String | file |
| action | 必选参数, 上传的地址 | String | 无 |
| data | 可选参数, 上传所需参数 | Object | 无 |
| multiple | 可选参数, 是否支持多选文件,支持ie10+ | Boolean | false |
| accept | 可选参数, 接受上传的文件类型, 详见input accept Attribute | String | 无 |
| onError | 可选参数, error callback |Function | 无 |
| onSuccess | 可选参数, success callback | Function | 无 |
| onProgress | 可选参数, progress callback, 现代浏览器有效 | Function | 无 |
| urlResolver| 通过解析请求返回数据,获得文件上传的远程地址 | Function |
`function() { return JSON.parse(ret).url }`
|
| limit | 文件上传数量的限制 | Number | Number.MAX_VALUE |
| multiple | 可选参数, 是否支持多选文件,支持
`ie10+`
| Boolean | false |
| accept | 可选参数, 接受上传的文件类型, 详见 input accept Attribute | String | 无 |
| onChange | 可选参数, 上传文件改变时的状态,详见 onChange | Function | 无 |
### on
Error
### on
Change
错误回调,有三个参数返回
:
文件状态改变的回调,返回为
:
1.
`err`
请求返回错误信息
2.
`responce`
请求响应,包括错误状态码等信息
3.
`file`
错误的文件对象
```
js
{
file
:
{
...
},
fileList
:
[
...
],
event
:
{
...
}
}
```
### onSuccess
1.
`file`
当前操作的文件对象。
成功回调,返回两个参数
```
js
{
uid
:
'
uid
'
,
// 文件唯一标识,建议设置为负数,防止和内部产生的 id 冲突
name
:
'
xx.png
'
// 文件名
status
:
'
done
'
,
// 状态:uploading done
response
:
'
{"status":"success"}
'
// 服务端响应内容
}
```
1.
`result`
上传图片返回结果
2.
`file`
文件对象
2.
`fileList`
当前的文件列表。
3.
`event`
上传中的服务端响应内容,包含了上传进度等信息,高级浏览器支持。
## 显示下载链接
请使用 fileList 属性设置数组项的 url 属性进行展示控制。
components/upload/uploadList.jsx
浏览文件 @
b6ec8b9e
...
...
@@ -22,36 +22,29 @@ export default React.createClass({
}
},
handleClose
(
file
)
{
let
items
=
this
.
state
.
items
;
let
removeItem
=
getFileItem
(
file
,
items
);
if
(
removeItem
)
{
items
.
splice
(
items
.
indexOf
(
removeItem
),
1
);
}
this
.
setState
({
items
:
items
});
this
.
props
.
onRemove
(
file
.
file
);
this
.
props
.
onRemove
(
file
);
},
render
()
{
let
items
=
this
.
state
.
items
;
let
downloadItem
=
(
file
)
=>
{
let
statusIcon
=
file
.
status
===
'
done
'
?
<
i
className
=
{
'
anticon anticon-check
'
+
prefixCls
+
'
-success-icon
'
}
></
i
>
:
let
list
=
this
.
state
.
items
.
map
((
file
)
=>
{
let
statusIcon
=
file
.
status
===
'
done
'
?
<
i
className
=
{
'
anticon anticon-check
'
+
prefixCls
+
'
-success-icon
'
}
></
i
>
:
<
i
className
=
"anticon anticon-loading"
></
i
>;
let
filename
=
file
.
url
?
<
a
className
=
{
prefixCls
+
'
-item-name
'
}
href
=
{
file
.
url
}
_target
=
"_blank"
>
{
file
.
filename
}
</
a
>
:
<
b
className
=
{
prefixCls
+
'
-item-name
'
}
>
{
file
.
filename
}
</
b
>;
let
filename
=
file
.
url
?
<
a
className
=
{
prefixCls
+
'
-item-name
'
}
href
=
{
file
.
url
}
_target
=
"_blank"
>
{
file
.
name
}
</
a
>
:
<
b
className
=
{
prefixCls
+
'
-item-name
'
}
>
{
file
.
name
}
</
b
>;
return
(
<
div
className
=
{
prefixCls
+
'
-list-item
'
}
key
=
{
file
.
index
}
>
<
div
className
=
{
prefixCls
+
'
-list-item
'
}
key
=
{
file
.
uid
}
>
{
statusIcon
}
{
filename
}
<
i
className
=
"anticon anticon-cross"
ref
=
"theCloseBtn"
onClick
=
{
this
.
handleClose
.
bind
(
this
,
file
)
}
></
i
>
</
div
>
);
};
return
(
<
div
className
=
{
prefixCls
+
'
-list
'
}
>
}
)
;
return
<
div
className
=
{
prefixCls
+
'
-list
'
}
>
<
Animate
transitionName
=
{
prefixCls
+
'
-margin-top
'
}
>
{
items
.
map
(
downloadItem
)
}
{
list
}
</
Animate
>
</
div
>
)
;
</
div
>;
}
});
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录