Dropzone JS的载波。是否可以将它们与嵌套属性一起使用? [英] Carrierwave with Dropzone JS. Is it possible to use these with nested attributes?

查看:56
本文介绍了Dropzone JS的载波。是否可以将它们与嵌套属性一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我有几种使用嵌套属性的表格。我最近发现有关Dropzone JS的信息,所以我想以我使用的各种形式实现它。

Currently, I have several forms that work with nested attributes. I found out recently about Dropzone JS, so I wanted to implement it in various forms I'm using.

我有两个类似的模型:

游戏

class Games < ActiveRecord::base
    has_many :screenshots, dependent: :destroy

    accepts_nested_attributes_for :screenshots, allow_destroy: true
end

屏幕截图

class Screenshot < ActiveRecord::Base
    belongs_to :game

    mount_uploader :ssfile, ScreenshotUploader
end

通常,我会用以下方式处理它:

Normally, I'd handle it with something like this:

new.html.haml

- content_for :breadcrumbs do
  %h3.text-center New Game
.col-md-12#content
  .row
    = render 'form'
  .row
    .col-md-12
      = link_to 'Back', games_path

_form.html.haml

.col-md-12
  = form_for @game, :html => {:class => 'form-horizontal form-bordered'} do |f|
    .section-title
      %h3 General Data
    .well
      .form-group
        =f.label :title, :class => 'col-md-2'
        .col-md-6
          = f.text_field :title, :class => 'form-control'
      .form-group
        = f.label :platform, :class => 'col-md-2'
        .col-md-6
          .input-group
            = f.text_field :platform, :class => 'form-control'
    .section-title
      %h3 Screenshots
    .well#screenshots
      =f.fields_for :screenshots do |i|
        =render 'screenshot_fields', :f => i
        %hr
      .links
        =link_to_add_association 'Add Screenshot', f, :screenshots, :class => 'btn btn-default'
    .row
      .col-md-12
        .actions
          = f.submit 'Save', :class => 'btn btn-default'

_screenshot_fields.html.haml

.form-group
  -if f.object.ssfile?
    .col-md-2
      =image_tag(f.object.ssfile_url(:thumb))
  .col-md-4
    %p
      =f.file_field :ssfile, :class => 'styledfileinput'
  -if f.object.ssfile?
    .col-md-2
      %p
        =f.check_box :_destroy
        =f.label :_destroy, 'Remove'

这很好。当您单击添加屏幕截图时,它将加载 link_to_add_association 帮助器,该帮助器是名为Cocoon的gem的一部分。该助手将创建必要的JS,以向表单(在本例中为文件输入)中添加代码的块,尽管通常您会有更多其他类型的输入,而不只是一个。

This works fine. When you click on "Add Screenshot", it loads the link_to_add_association helper, which is part of a gem called Cocoon. This helper will create the necessary JS to add a "block" of code to a form, in this case a file input, though usually you'd have more inputs of other kinds instead of just one.

我想用多文件放置区替换 link_to_add_association 添加的块。

I want to replace the blocks added by link_to_add_association with a multi-file drop zone.

我对 new.html.haml 视图进行了以下更改:

I've made the following changes to the new.html.haml view:

.col-md-12
  = form_for @game, :html => {:class => 'form-horizontal form-bordered', :id => 'gameform'} do |f|
    -# *snip*
    .well#screenshots
      - @game.screenshots.each do |i|
        =image_tag i.ssfile_url(:thumb)
      %hr
    .row
      .col-md-12
        .actions
          = f.submit 'Save', :class => 'btn btn-default'

我添加了 #gameform form_for 元素,并替换了显示图片的循环。到现在为止还挺好。现在的问题是我不知道文件应该如何与表单进行交互。

I added #gameform to the form_for element, and replaced the loop that shows the pictures. So far so good. The problem now is that I don't know how are the files supposed to interact with the form.

我在加载Dropzone配置的Coffeescript上有此文件:

I have this on a coffeescript that's loading the Dropzone configuration:

ready = ->
  if $('#gameform').length > 0
    didthiswork = new Dropzone("#gameform", {
      paramName: "game[screenshot_attributes][ssfile]"
    })
  else
    console.log('ruh roh')


$(document).on('page:load ready', ready)

现在,我可以单击表单中的任意位置,它将显示上载对话框(这本身就是另一个问题),但是一旦我选择了图片,这些将不正确已保存。有没有办法使 fields_for 起作用?我还有很多其他表单都使用非常相似的配置,因此,我宁愿不必更改应用程序的整个逻辑(如果可能的话)。

Right now, I can click anywhere in the form and it will bring the upload dialog (which is another problem on itself), but once I pick the pictures, these aren't properly saved. Is there a way to make this work with fields_for? I have a lot of other forms that use a very similar configuration, so I'd much prefer not having to change the entire logic of my application (if possible).

我认为我已经取得了一些进展。我设法使表格发送数据,但是他们没有达到我的期望。

I think I've made some progress. I've managed to make the form send the data, however they're not arriving how I'm expecting it.

我使用此信息调整了配置链接: https://github.com/enyo/dropzone/wiki / Combine-normal-form-with-Dropzone

I tweaked the configuration, using the information in this link: https://github.com/enyo/dropzone/wiki/Combine-normal-form-with-Dropzone

在我的脚本中产生类似这样的结果:

Resulting in something like this on my coffescript:

Dropzone.options.articuloform =
  autoProcessQueue: false
  uploadMultiple: true
  paramName: "game[screenshot_attributes][ssfile]"
  parallelUploads: 100
  maxFiles: 100
  init: ->
    myDropzone = this
    # First change the button to actually tell Dropzone to process the queue.
    @element.querySelector('input[type=submit]').addEventListener 'click', (e) ->
      # Make sure that the form isn't actually being sent.
      e.preventDefault()
      e.stopPropagation()
      myDropzone.processQueue()
      return
    # Listen to the sendingmultiple event. In this case, it's the sendingmultiple event instead
    # of the sending event because uploadMultiple is set to true.
    @on 'sendingmultiple', ->
      # Gets triggered when the form is actually being sent.
      # Hide the success button or the complete form.
      return
    @on 'successmultiple', (files, response) ->
      # Gets triggered when the files have successfully been sent.
      # Redirect user or notify of success.
      return
    @on 'errormultiple', (files, response) ->
      # Gets triggered when there was an error sending the files.
      # Maybe show form again, and notify user of error
      return
    return

这样可以防止在我选择图像时自动上传数据(很棒),但是,一旦按下Submit(提交)按钮,则数据以错误的结构到达。他们从数据中这样到达:

This prevents the automatic data upload when I select images (which is great), however, once I press the Submit button, the data is arriving with the wrong structure. They're arriving like this in the from data:

Parameters: {

  "utf8"=>"âœ"",
  "authenticity_token"=>"l2siCG2D4xW0eto48WM152MTusc6K5cQYem8K2a9c/Y=",
  "game"=>{
    "title"=>"Super Amazing AAA Title",
    "platform"=>"Xbox One",
    "screenshot_attributes"=>{
      "ssfile"=>{
        "0"=>#<ActionDispatch::Http::UploadedFile:0x000000055c7e98 @tempfile=#<Tempfile:/tmp/RackMultipart20150408-9276-14rfzqm>,
          @original_filename="screenshot01.png",
          @content_type="image/png",
          @headers="Content-Disposition: form-data; name=\"game[screenshot_attributes][ssfile][0]\"; filename=\"screenshot01.png\"\r\nContent-Type: image/png\r\n">,
        "1"=>#<ActionDispatch::Http::UploadedFile:0x000000055c7df8 @tempfile=#<Tempfile:/tmp/RackMultipart20150408-9276-1opclgk>,
          @original_filename="screenshot02.png",
          @content_type="image/png",
          @headers="Content-Disposition: form-data; name=\"game[screenshot_attributes][ssfile][1]\"; filename=\"screenshot02.png\"\r\nContent-Type: image/png\r\n">,
        "2"=>#<ActionDispatch::Http::UploadedFile:0x000000055c7d30 @tempfile=#<Tempfile:/tmp/RackMultipart20150408-9276-16r4kdq>,
          @original_filename="screenshot03.png",
          @content_type="image/png",
          @headers="Content-Disposition: form-data; name=\"game[screenshot_attributes][ssfile][2]\"; filename=\"screenshot03.png\"\r\nContent-Type: image/png\r\n">,
        "3"=>#<ActionDispatch::Http::UploadedFile:0x000000055c7c90 @tempfile=#<Tempfile:/tmp/RackMultipart20150408-9276-qp1au3>,
          @original_filename="screenshot04.png",
          @content_type="image/png",
          @headers="Content-Disposition: form-data; name=\"game[screenshot_attributes][ssfile][3]\"; filename=\"screenshot04.png\"\r\nContent-Type: image/png\r\n">,
        "4"=>#<ActionDispatch::Http::UploadedFile:0x000000055c7ba0 @tempfile=#<Tempfile:/tmp/RackMultipart20150408-9276-8g3pap>,
          @original_filename="screenshot05.png",
          @content_type="image/png",
          @headers="Content-Disposition: form-data; name=\"game[screenshot_attributes][ssfile][4]\"; filename=\"screenshot05.png\"\r\nContent-Type: image/png\r\n">
        }
      }
    },
  "null"=>"",
  "commit"=>"Save",
  "id"=>"2"
}

重要的是每个段的名称由于 game [screenshot_attributes] [ssfile] [XXXX] 错误,正确的格式应为 game [screenshot_attributes] [XXXX] [ssfile] 。我可以在上面粘贴的部分中进行配置,但重要的部分是 paramName 部分,该部分为 paramName:游戏[screenshot_attributes] [ssfile]

The important part is in the name of each segment, they're arriving as game[screenshot_attributes][ssfile][XXXX] which is wrong, the right format should be game[screenshot_attributes][XXXX][ssfile]. I can configure this in the part I pasted above, but the important part is the paramName section, which I have as paramName: "game[screenshot_attributes][ssfile]".

如果有人可以提供任何线索,我将不胜感激。

If anyone could have any clues, I'd greatly appreciate.

推荐答案

最后找到了一种使dropzone.js使用rails嵌套属性的方法,您必须编辑dropzone.js来设置rails的格式多个附件的嵌套属性数组。

Finally found a way to make dropzone.js working with rails nested attributes. You have to edit dropzone.js to set the format of rails nested attribute array for multiple attachments.

Dropzone.prototype._getParamName = function(n) {
  if (typeof this.options.paramName === "function") {
    return this.options.paramName(n);
  } else {
    return "" + this.options.paramName1 + (this.options.uploadMultiple ? "[" + n + "]" : "") + this.options.paramName2 + "";
  }
};

然后在dropzone初始化javascript中初始化两个参数:

Then inside dropzone initialization javascript initialize both params:

Dropzone.options.newTicket =
        clickable:'#previews'
        previewsContainer: "#previews"
        dictDefaultMessage: "Drop files here or click to select files"
        autoProcessQueue: false
        uploadMultiple: true
        paramName1: "ticket[attachments_attributes]"
        paramName2: "[file]"
        parallelUploads: 5
        maxFiles: 5
        addRemoveLinks: true

这篇关于Dropzone JS的载波。是否可以将它们与嵌套属性一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆