我正在使用dropzonejs-rails gem并结合dropzone进行文件管理。我上传工作很棒,但删除文件让我感到痛苦。我无法让侦听器附加,以便ajax会命中我的服务器。我的强项是Ruby on Rails,我只有有限的javascript经验,所以这可能是真正的问题......但也许有人可以帮助我解决我[可耻的] 2天的斗争。
Dropzone在上传文件后正在dropzone中正确显示previewTemplate,而addRemoveLinks: true
正在缩略图预览中显示删除链接。我的目标是,当用户单击文件的删除链接时,应该向服务器发送请求以删除该文件。我尝试了许多不同的方法来自博客,dropzone常见问题解答,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)应用程序获得这种方法(或更好的方法?)
如果您需要任何其他信息或代码,请与我们联系。谢谢!
答案 0 :(得分:0)
我最终想出了如何通过"删除文件"使其通过ajax请求进入Rails服务器。通过addRemoveLinks选项随附dropzonejs-rails的按钮(设置为true时)。 (see dropzonejs.com for more info on that)这是在@simmi simmi's answer here的帮助下完成的。
所以,如果有人想知道,这里是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进行文件上传。我确信它上传宝石的其他文件(纸夹,蜻蜓等)非常相似。