Symfony 2 表单集合字段与文件类型

14

我想用POST请求上传多个文件(不使用Ajax)。我可以像这样使用Symfony 2表单集合字段和文件类型吗:

实体中的代码:

public $pictures;

public function __construct()
{
    $this->pictures = new \Doctrine\Common\Collections\ArrayCollection();
}

表单类中的代码:

$builder->add('pictures', 'collection', array(
        'type' => 'file',
        'required' => false,
        'attr' => array(
            'multiple' => 'multiple'
        )
));

Twig中的代码:

{% for picture in form.pictures %}
    <td>
        {{ form_widget(picture) }}
    </td>
{% endfor %}

我尝试过,但好像不起作用。它没有显示任何错误,但也没有显示输入文件。有什么想法吗?

4个回答

5
要实际呈现输入类型,您需要将集合中的allow_add选项设置为true,并使用集合的表单原型、JavaScript和按钮添加文件字段。
这是一份基于文档(集合-添加和删除)的例子。
表单:
<form action="..." method="POST" {{ form_enctype(form) }}>
{# ... #}

{# store the prototype on the data-prototype attribute #}
<ul id="image-container" class="collection-container" data-prototype="{{ form_widget(form.images.vars.prototype) | e }}">
{% for imageField in form.images%}
    <li>
        {{ form_widget(imageField) }}
    </li>
{% endfor %}
</ul>

<a href="#" class="collection-add" data-collection="image-container">Add image</a>

</form>

脚本内容如下:
<script type="text/javascript">
  var imageCount;

  jQuery(document).ready(function() {
    $(document).on('click', '.collection-add', function () {
        var $collectionContainer = $('#' + $(this).data('collection'));
        if(!imageCount){imageCount = $collectionContainer.children().length;}
        var prototype = $collectionContainer.attr('data-prototype');
        var item = prototype.replace(/__name__/g, imageCount);
        $collectionContainer.append(item);
        imageCount++;
    });
  })
</script>

这只是一个想法,根据您的需求仍有很多工作需要完成。如果这不是您要寻找的内容,也许您可以将添加按钮点击称为解决方法。


4

如果您想显示多个输入字段,不,它不会起作用。集合类型要求您在渲染字段之前提供一些数据。我已经尝试过了,并创建了一个单独的实体(例如文件),并将其添加到我的目标实体的关系中。

示例:

class File
{
    // properties

    public $file; // this holds an UploadedFile object

    // getters, setters
}

文件类型:

....

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('file', 'file', [
            'required' => false
        ])
    ;
}

产品:

class Product
{
    // properties

    private $images; // ManyToMany relationship

    // setters, getters
}

产品类型:

->add('images', 'collection', [
    'type' => 'YOUR_FILE_TYPE_NAME',
    'by_reference' => false,
    'required' => false
])

产品控制器:

public function someAction()
{
    ...

    $image = new File();
    $product->addImage($image);

}

我知道这个解决方案可能有些过度,并且会创建额外的表格,但它是有效的。


2

您需要在集合中指定小部件的类型

请查看:http://symfony.com/doc/2.0/reference/forms/types/collection.html

$builder->add('pictures', 'collection', array(
  // each item in the array will be an "email" field
  'type'   => 'file',
  // these options are passed to each "email" type
  'options'  => array(
    'required'  => false,
  ),
));

为了进一步阅读,我建议

http://symfony.com/doc/2.0/reference/forms/types/file.html

此外,您需要添加一些内容到这个集合中以进行显示,因为在实体的构造函数中它将为空。


谢谢您的回答。我尝试了一百次,但它没起作用。 - Sukhrob
这不会创建一个文件选择框,无法同时选择多个文件。 - Rvanlaak
我认为您需要使用一些软件包来处理多个上传。因为默认情况下,它将创建多个单个文件上传。 - Max Małecki

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接