2014-07-06 2 views
0

나는 파일 관리를 위해 dropzonejs-rails gem과 dropzone을 통합하고 있습니다. 업로드 작업이 훌륭하지만 파일을 삭제하면 고민이되고 있습니다. 아약스가 내 서버에 충돌 할 수 있도록 리스너를 연결할 수 없습니다. 루프트 한자는 Ruby on Rails이고, 제한된 자바 스크립트 경험이 있기 때문에 아마 여기 진짜 문제 일 것입니다.하지만 어쩌면 누군가가 저의 부끄러운 2 일간의 투쟁을 해결할 수 있습니다.레일즈가있는 Dropzonejs - 서버에서 파일 삭제하기

파일이 업로드되면 Dropzone에서 previewTemplate이 올바르게 표시되고 addRemoveLinks: true은 축소판 미리보기에서 제거 링크를 표시합니다. 내 목표는 사용자가 파일의 제거 링크를 클릭하면 서버에 파일을 삭제하라는 요청을 보내야한다는 것입니다. 블로그, dropzone FAQ, github 문제 등에서 많은 접근 방식을 시도했습니다. 가장 가까운 것은 성공입니다 : https://github.com/enyo/dropzone/issues/456.

성공적으로 업로드하면 .dz-remove 버튼에 이벤트 리스너를 추가하려고 시도했습니다. 이 리스너는 파일을 삭제하라는 ajax 요청으로 서버를 히트하기위한 것입니다. 현재 미리보기 축소판에서 제거 링크를 클릭하면 dropzone에서 미리보기 축소판 만 제거되지만 서버에는 ajax가 적용되지 않습니다. 여기에 자바 스크립트 코드 :

// 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); 
    }); 
    } 
}; 

따라서는 클릭 삭제 링크와 연결된 파일 정보를 찾을해야하고, 보내는 삭제 요청에 대한 서버에 대한 정보. 누구든지 Ruby on Rails (Rails 4) 응용 프로그램에서 Javascript를 사용하여이 접근법을 성공적으로 얻었습니까?

추가 정보 나 코드가 필요한 경우 알려주십시오. 감사!

답변

0

결국 addRemoveLinks 옵션 (true로 설정된 경우)을 통해 dropzonejs-rails와 함께 제공되는 "파일 제거"버튼을 통해 레일즈 서버를 공격하는 방법을 알아 냈습니다. (see dropzonejs.com for more info on that) 이것은 @simmi simmi's answer here의 도움으로 완성되었습니다.

누군가 궁금한 점이 있으시면 여기에 coffeescript의 코드가 있습니다. (미안 swchcheroo 중반 질문 .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을 사용하여 만들어 졌음에 유의하십시오. 나는 보석 (paperclip, 잠자리, 등등)을 거기 밖으로 올려 놓는 다른 파일을 위해 확실히 유사하다고 확신한다.