我正在尝试在ReactJS下应用Dropzone bootstrap example,如下面的代码所示。
但由于某种原因,“开始上传/取消上传”和“进度条”的行为方式不一致。
示例1:即使我取消了要上传的所有文件,进度条也会显示无穷无尽的进度。 示例2:开始上传单个文件将不会执行任何操作。
有人可以告诉我我在做错了什么/在这里失踪了,我怎么能像这个例子一样做这个工作?
注意:如果可能,请使用Refs
进行第一次回复import React from 'react';
import { connect } from 'react-redux';
@connect((state) => state)
export default class DZUploader extends React.Component {
componentDidMount() {
let previewNode = document.querySelector("#template");
previewNode.id = "";
let previewTemplate = previewNode.parentNode.innerHTML;
previewNode.parentNode.removeChild(previewNode);
let myDropzone = new Dropzone(document.body, {
url: "/target-url", // Set the url
paramName: "file", // The name that will be used to transfer the file
maxFilesize: 2, // MB
thumbnailWidth: 80,
thumbnailHeight: 80,
parallelUploads: 20,
previewTemplate: previewTemplate,
autoQueue: false,
previewsContainer: "#previews",
clickable: ".fileinput-button",
});
myDropzone.on('addedfile', function(file){
console.log(file);
file.previewElement.querySelector(".start").onclick = function() { myDropzone.enqueueFile(file); };
});
myDropzone.on('totaluploadprogress', function(progress){
console.log(progress);
document.querySelector("#total-progress .progress-bar").style.width = progress + "%";
});
myDropzone.on('sending', function(file){
// Show the total progress bar when upload starts
document.querySelector("#total-progress").style.opacity = "1";
// And disable the start button
file.previewElement.querySelector(".start").setAttribute("disabled", "disabled");
});
myDropzone.on('queuecomplete', function(progress){
document.querySelector("#total-progress").style.opacity = "0";
});
document.querySelector("#actions .start").onclick = function() {
myDropzone.enqueueFiles(myDropzone.getFilesWithStatus(Dropzone.ADDED));
};
document.querySelector("#actions .cancel").onclick = function() {
myDropzone.removeAllFiles(true);
};
}
render() {
return (
<div>
<div id="actions" className="row">
<div className="col-lg-7">
<span className="btn btn-success fileinput-button dz-clickable">
<i className="glyphicon glyphicon-plus"></i>
<span>Add files...</span>
</span>
<button type="submit" className="btn btn-primary start">
<i className="glyphicon glyphicon-upload"></i>
<span>Start upload</span>
</button>
<button type="reset" className="btn btn-warning cancel">
<i className="glyphicon glyphicon-ban-circle"></i>
<span>Cancel upload</span>
</button>
</div>
<div className="col-lg-5">
<span className="fileupload-process">
<div id="total-progress" className="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
<div className="progress-bar progress-bar-success" data-dz-uploadprogress=""></div>
</div>
</span>
</div>
</div>
<div className="table table-striped" className="files" id="previews">
<div id="template" className="file-row">
<div>
<span className="preview"><img data-dz-thumbnail /></span>
</div>
<div>
<p className="name" data-dz-name></p>
<strong className="error text-danger" data-dz-errormessage></strong>
</div>
<div>
<p className="size" data-dz-size></p>
<div className="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
<div className="progress-bar progress-bar-success" data-dz-uploadprogress></div>
</div>
</div>
<div>
<button className="btn btn-primary start">
<i className="glyphicon glyphicon-upload"></i>
<span>Start</span>
</button>
<button data-dz-remove className="btn btn-warning cancel">
<i className="glyphicon glyphicon-ban-circle"></i>
<span>Cancel</span>
</button>
<button data-dz-remove className="btn btn-danger delete">
<i className="glyphicon glyphicon-trash"></i>
<span>Delete</span>
</button>
</div>
</div>
</div>
</div>
);
}
}
答案 0 :(得分:6)
3件事:
使用componentDidMount生命周期方法并不意味着$
(JQuery)和dropzone
已经加载到DOM中
使用React Refs
代替选择器,以便您的组件保持一致
您应该使用导入键导入dropzone
对象,并避免使用jquery依赖项(import dropzone from 'dropzone'
)。
结论:
当你不需要时,避免使用Jquery,至少在这种情况下是这样。
作为我的建议的结论,您的组件应如下所示:
import React from 'react';
import { connect } from 'react-redux';
import Dropzone from 'dropzone';
@connect((state) => state)
export default class DZUploader extends React.Component {
constructor(props) {
super(props);
this.focus = this.focus.bind(this);
this.onAddedfile = this.onAddedfile.bind(this);
this.onTotaluploadprogress = this.onTotaluploadprogress.bind(this);
this.onSending = this.onSending.bind(this);
this.onQueuecomplete = this.onQueuecomplete.bind(this);
this.onActionStartClick = this.onActionStartClick.bind(this);
this.onActionCancelClick = this.onActionCancelClick.bind(this);
}
componentDidMount() {
const previewNode = this.divTemplate;
previewNode.id = "";
const previewTemplate = previewNode.parentNode.innerHTML;
previewNode.parentNode.removeChild(previewNode);
const myDropzone = new Dropzone(document.body, {
url: "/target-url", // Set the url
paramName: "file", // The name that will be used to transfer the file
maxFilesize: 2, // MB
thumbnailWidth: 80,
thumbnailHeight: 80,
parallelUploads: 20,
previewTemplate: previewTemplate,
autoQueue: false,
previewsContainer: "#previews",
clickable: ".fileinput-button",
});
myDropzone.on('addedfile', onAddedfile);
myDropzone.on('totaluploadprogress', onTotaluploadprogress);
myDropzone.on('sending', onSending);
myDropzone.on('queuecomplete', onQueuecomplete);
this.actionStart.onclick = onActionStartClick;
this.actionStart.onclick = onActionCancelClick;
}
onAddedfile(file) {
console.log(file);
file.previewElement.querySelector(".start").onclick = function() { myDropzone.enqueueFile(file); };
}
onTotaluploadprogress(progress) {
console.log(progress);
this.progressBar.style.width = progress + "%";
}
onSending(file) {
// Show the total progress bar when upload starts
this.totalProgress.style.opacity = "1";
// And disable the start button
file.previewElement.querySelector(".start").setAttribute("disabled", "disabled");
}
onQueuecomplete(progress) {
this.totalProgress.style.opacity = "0";
}
onActionStartClick() {
myDropzone.enqueueFiles(myDropzone.getFilesWithStatus(Dropzone.ADDED));
}
onActionCancelClick() {
myDropzone.removeAllFiles(true);
}
render() {
return (
<div>
<div id="actions" className="row">
<div className="col-lg-7">
<span className="btn btn-success fileinput-button dz-clickable">
<i className="glyphicon glyphicon-plus"></i>
<span>Add files...</span>
</span>
<button type="submit" className="btn btn-primary start" ref={(button) => { this.actionStart = button; }}>
<i className="glyphicon glyphicon-upload"></i>
<span>Start upload</span>
</button>
<button type="reset" className="btn btn-warning cancel" ref={(button) => { this.actionCancel = button; }}>
<i className="glyphicon glyphicon-ban-circle"></i>
<span>Cancel upload</span>
</button>
</div>
<div className="col-lg-5">
<span className="fileupload-process">
<div id="total-progress" ref={(div) => { this.totalProgress = div; }} className="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
<div className="progress-bar progress-bar-success" ref={(div) => { this.progressBar = div; }} data-dz-uploadprogress=""></div>
</div>
</span>
</div>
</div>
<div className="table table-striped" className="files" id="previews">
<div id="template" ref={(div) => { this.divTemplate = div; }} className="file-row">
<div>
<span className="preview"><img data-dz-thumbnail /></span>
</div>
<div>
<p className="name" data-dz-name></p>
<strong className="error text-danger" data-dz-errormessage></strong>
</div>
<div>
<p className="size" data-dz-size></p>
<div className="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
<div className="progress-bar progress-bar-success" data-dz-uploadprogress></div>
</div>
</div>
<div>
<button className="btn btn-primary start">
<i className="glyphicon glyphicon-upload"></i>
<span>Start</span>
</button>
<button data-dz-remove className="btn btn-warning cancel">
<i className="glyphicon glyphicon-ban-circle"></i>
<span>Cancel</span>
</button>
<button data-dz-remove className="btn btn-danger delete">
<i className="glyphicon glyphicon-trash"></i>
<span>Delete</span>
</button>
</div>
</div>
</div>
</div>
);
}
}
答案 1 :(得分:1)
以下是React + Dropzone + Relay使用情况的演示。
在组件中使用Dropzone。
<Dropzone style={{disply: 'none'}} disableClick={true} ref="dropzone" onDrop={this.onDrop}/>
实施onDrop
功能,此处我正在进行中继突变,如果您不使用中继,那么此处应该发布上传文件的请求。
onDrop: function(files) {
/*
* TODO fire mutliple mutations triggars warnings
*/
files.forEach((file)=> {
Relay.Store.commitUpdate(
new AddImageMutation({
file,
images: this.props.User,
})
);
});
}
上述代码可在relay-gallery
中找到