J'ai cherché partout de l'aide pour créer un composant permettant de gérer le téléchargement de fichiers depuis React vers un noeud final que j'ai configuré.).
J'ai essayé de nombreuses options, y compris l'intégration filedropjs . J'ai décidé de ne pas le faire parce que je n'ai pas le contrôle sur les éléments qu'il installe dans le DOM avec le new FileDrop('zone', options);
Voici ce que j'ai jusqu'à présent:
module.exports = React.createClass({
displayName: "Upload",
handleChange: function(e){
formData = this.refs.uploadForm.getDOMNode();
jQuery.ajax({
url: 'http://example.com',
type : 'POST',
xhr: function(){
var myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){
myXhr.upload.addEventListener('progress',progressHandlingFunction, false);
}
return myXhr;
},
data: formData,
cache: false,
contentType: false,
processData: false,
success: function(data){
alert(data);
}
});
},
render: function(){
return (
<form ref="uploadForm" className="uploader" encType="multipart/form-data" onChange={this.handleChange}>
<input ref="file" type="file" name="file" className="upload-file"/>
</form>
);
}
});
},
render: function(){
console.log(this.props.content);
if(this.props.content != ""){
return (
<img src={this.props.content} />
);
} else {
return (
<form className="uploader" encType="multipart/form-data" onChange={this.handleChange}>
<input ref="file" type="file" name="file" className="upload-file"/>
</form>
);
}
}
});
Si quelqu'un pouvait me diriger dans la bonne direction, je lui ferais des câlins virtuels. J'ai beaucoup travaillé là-dessus. J'ai l'impression d'être proche, mais pas tout à fait là.
Merci!
J'ai également travaillé sur cette question assez longtemps. C'est ce que je suis venu avec.
Un composant Dropzone
, associé à l'utilisation de superagent .
// based on https://github.com/paramaggarwal/react-dropzone, adds image preview
const React = require('react');
const _ = require('lodash');
var Dropzone = React.createClass({
getInitialState: function() {
return {
isDragActive: false
}
},
propTypes: {
onDrop: React.PropTypes.func.isRequired,
size: React.PropTypes.number,
style: React.PropTypes.object
},
onDragLeave: function(e) {
this.setState({
isDragActive: false
});
},
onDragOver: function(e) {
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
this.setState({
isDragActive: true
});
},
onDrop: function(e) {
e.preventDefault();
this.setState({
isDragActive: false
});
var files;
if (e.dataTransfer) {
files = e.dataTransfer.files;
} else if (e.target) {
files = e.target.files;
}
_.each(files, this._createPreview);
},
onClick: function () {
this.refs.fileInput.getDOMNode().click();
},
_createPreview: function(file){
var self = this
, newFile
, reader = new FileReader();
reader.onloadend = function(e){
newFile = {file:file, imageUrl:e.target.result};
if (self.props.onDrop) {
self.props.onDrop(newFile);
}
};
reader.readAsDataURL(file);
},
render: function() {
var className = 'dropzone';
if (this.state.isDragActive) {
className += ' active';
};
var style = {
width: this.props.size || 100,
height: this.props.size || 100,
borderStyle: this.state.isDragActive ? 'solid' : 'dashed'
};
return (
<div className={className} onClick={this.onClick} onDragLeave={this.onDragLeave} onDragOver={this.onDragOver} onDrop={this.onDrop}>
<input style={{display: 'none' }} type='file' multiple ref='fileInput' onChange={this.onDrop} />
{this.props.children}
</div>
);
}
});
module.exports = Dropzone
Utiliser le Dropzone
.
<Dropzone onDrop={this.onAddFile}>
<p>Drag & drop files here or click here to browse for files.</p>
</Dropzone>
Lorsqu'un fichier est ajouté à la zone de dépôt, ajoutez-le à votre liste de fichiers à télécharger. Je l'ajoute à mon magasin de flux.
onAddFile: function(res){
var newFile = {
id:uuid(),
name:res.file.name,
size: res.file.size,
altText:'',
caption: '',
file:res.file,
url:res.imageUrl
};
this.executeAction(newImageAction, newFile);
}
Vous pouvez utiliser l'imageUrl pour afficher un aperçu du fichier.
<img ref="img" src={this.state.imageUrl} width="120" height="120"/>
Pour télécharger les fichiers, obtenez la liste des fichiers et envoyez-les via superagent. J'utilise flux, alors je reçois la liste des images de ce magasin.
request = require('superagent-bluebird-promise')
Promise = require('bluebird')
upload: function(){
var images = this.getStore(ProductsStore).getNewImages();
var csrf = this.getStore(ApplicationStore).token;
var url = '/images/upload';
var requests = [];
var promise;
var self = this;
_.each(images, function(img){
if(!img.name || img.name.length == 0) return;
promise = request
.post(url)
.field('name', img.name)
.field('altText', img.altText)
.field('caption', img.caption)
.field('size', img.size)
.attach('image', img.file, img.file.name)
.set('Accept', 'application/json')
.set('x-csrf-token', csrf)
.on('progress', function(e) {
console.log('Percentage done: ', e.percent);
})
.promise()
.then(function(res){
var newImg = res.body.result;
newImg.id = img.id;
self.executeAction(savedNewImageAction, newImg);
})
.catch(function(err){
self.executeAction(savedNewImageErrorAction, err.res.body.errors);
});
requests.Push(promise);
});
Promise
.all(requests)
.then(function(){
console.log('all done');
})
.catch(function(){
console.log('done with errors');
});
}
Cela peut aider
var FormUpload = React.createClass({
uploadFile: function (e) {
var fd = new FormData();
fd.append('file', this.refs.file.getDOMNode().files[0]);
$.ajax({
url: 'http://localhost:51218/api/Values/UploadFile',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
alert(data);
}
});
e.preventDefault()
},
render: function() {
return (
<div>
<form ref="uploadForm" className="uploader" encType="multipart/form-data" >
<input ref="file" type="file" name="file" className="upload-file"/>
<input type="button" ref="button" value="Upload" onClick={this.uploadFile} />
</form>
</div>
);
}
});
emprunté à partir d'ici Comment envoyer des objets FormData avec Ajax-request dans jQuery?
J'étais confronté à la tâche d'obtenir ce comportement de type facebook ou gmail où votre cible de dépôt est mise en surbrillance dès que l'utilisateur commence à faire glisser un fichier n'importe où sur la fenêtre. Il n'y avait pas de solution standard React par glisser/déposer que je pouvais trouver. Donc, j'en ai créé une.
Il est censé être simple, vous fournissant une base pour personnaliser et personnaliser votre style. Il fournit de nombreux crochets pour vous permettre de le faire. Mais il y a aussi une démo qui vous donne un exemple à suivre.
Découvrez-le: https://www.npmjs.com/package/react-file-drop
Il existe un paquet Dropzone npm pour cela https://www.npmjs.com/package/react-dropzone