带Rails的Dropzonejs – 从服务器删除文件

我正在使用dropzonejs-rails gem并使用dropzone进行文件管理。 我上传工作很棒,但删除文件让我感到痛苦。 我无法让侦听器附加,以便ajax将命中我的服务器。 我的强项是Ruby on Rails,我只有有限的javascript经验,所以这可能是真正的问题……但也许有人可以帮助我解决我[可耻的] 2天的斗争。

Dropzone在上传文件后正在dropzone中正确显示previewTemplate, addRemoveLinks: true在缩略图预览上显示删除链接。 我的目标是在用户单击文件的删除链接时,应该向服务器发送请求以删除该文件。 我尝试了许多不同的方法来自博客,dropzone FAQ,github问题等。我最接近成功的是: https : //github.com/enyo/dropzone/issues/456 。

我尝试在成功上传后向.dz-remove按钮添加一个事件监听器。 此侦听器旨在使用ajax请求命中服务器以删除该文件。 目前,单击预览缩略图上的删除链接仅从dropzone中删除预览缩略图,但不会使用ajax命中服务器。 这是javascript代码:

 // Listening for Dropzone upload success // imageDropzone is the camelized version of the dropzone form's id. Dropzone.options.imageDropzone = { init: function() { this.on("success", function(file, response, event) { // Loads image ID to the file preview for use w/deletion var elem; elem = document.createElement('input'); elem.setAttribute("name", "id"); elem.setAttribute("value", response["id"]); elem.setAttribute("type", "hidden"); file.previewTemplate.appendChild(elem); // Add the listener to the dz-remove class link $('.dz-remove').on("click", (function(e) { var imageId, imageToken, _this; _this = this; e.preventDefault(); e.stopPropagation(); imageId = $(_this).parent().find('[name="id"]').val(); console.log(_this); console.log(imageId); console.log(imageToken); $.ajax({ url: "/remove_image", type: "DELETE", dataType: "script", data: { id: imageId } }); return false; }), false); }); } }; 

因此,它应该找到与单击的删除链接关联的文件信息,并将该信息发送到服务器以获取删除请求。 有人成功地使用Javascript为Ruby on Rails(Rails 4)应用程序获得了这种方法(或者更好的方法吗?)?

如果您需要任何其他信息或代码,请与我们联系。 谢谢!

我最终通过addRemoveLinks选项(当设置为true时)通过dropzonejs-rails附带的“remove file”按钮找到了如何通过ajax请求使其进入Rails服务器。 (有关详细信息,请参阅dropzonejs.com)这是在@simmi simmi的答案的帮助下完成的 。

所以,如果有人想知道,这是coffeescript中的代码。 (对不起切换器中间问题。如果你需要它以JS格式,使用js2coffee.org转换回JS格式,或者如果我收到请求,我可以发布它。)因为它在coffeescript中,解释注释将使用’#’符号在线添加。

/app/assets/javascripts/upload.js.coffee

  # Note that imageDropzone is the #id of MY dropzone HTML element. Yours may be called myDropzone or otherwise - tailor as needed. Dropzone.options.imageDropzone = init: -> @on "success", (file, response, event) -> #triggered by our render JSON's status: 200 "success" response rendered from controller on successful upload. # Append the image id as a hidden input elem = document.createElement('input') elem.setAttribute("name", "image[id]") elem.setAttribute("value", response["id"]) elem.setAttribute("type", "hidden") file.previewTemplate.appendChild elem # Append the image token as a hidden input. # Because images are uploaded as an association (Post model has_many :images), there needs to be a common reference so the Post controller can associate the proper pictures during creation of the Post. elem2 = document.createElement('input') elem2.setAttribute("name", "image[token]") elem2.setAttribute("value", response["token"]) elem2.setAttribute("type", "hidden") file.previewTemplate.appendChild elem2 # The "remove file" button's listener needs to be added through "file.previewTemplate" for it to work, but note that "click" does NOT work! # It seemed like the built-in listener gets the "click" call before this one we add here, so it never receives this. # So, I used a "mouseup" listener to have a fighting chance, and it worked. file.previewTemplate.addEventListener "mouseup", (e) -> _this = this e.preventDefault() e.stopPropagation() # These next two lines are me grabbing the database reference values I put into the previewTemplate (see above). These are passed through the Ajax call at params. I wanted them to come through hashed like params[:images][:id] & params[:images][:token] for easy use with strong_params. imageId = $(_this).parent().find('[name="image[id]"]').val() imageToken = $(_this).parent().find('[name="image[token]"]').val() $.ajax url: "/destroyimage" #This is the route I'm hitting to forward to controller type: "DELETE" dataType: "script" #Send as JS data: image: id: imageId token: imageToken false false 

这是控制器信息,以防它有用:

#应用程序/控制器/ images_controller.rb

 def create @image = current_user.images.build(image_params) # Build through the association respond_to do |format| if @image.save # Send Response: id/token for remove button; status 200 OK for Dropzone success format.json { render json: @image, id: @image.id, token: @image.token, :status => 200 } else # Send Response: status 400 ERROR for Dropzone failure format.json { render json: { error: @image.errors.full_messages }, :status => 400 } end end end def destroy image = current_user.images.where(token: image_params[:token]).where(id: image_params[:id]).take # Probably a little too redundant on security, but whatever respond_to do |format| if Image.destroy(image.id) format.json { head :ok, :status => 200 } else format.json { render json: { error: @image.errors.full_messages }, :status => 400 } end end end private def image_params # There's probably a better way to do this, but it worked for me. params[:image].present? ? params.require(:image).permit(:id, :filename, :token) : nil end 

此外,请注意,这是使用Rails CarrierWave gem进行文件上传。 我确信它与其他文件上传gem非常相似(回形针,蜻蜓等)。