【问题标题】:symfony form element optionssymfony 表单元素选项
【发布时间】:2012-12-24 09:02:50
【问题描述】:

好的,这有点令人费解,请耐心等待。我会尽量保持简洁明了。

我正在使用 Symfony2 非常好的表单构建器系统来进行简单的 crud,但是基本的文件上传元素并不能完全满足我的需求,所以我想通过添加缩略图预览和其他一些细节来扩展它。

读到这里,我发现我可以创建自己的自定义模板块来渲染文件元素:

http://symfony.com/doc/master/cookbook/form/form_customization.html#twig

这真的很酷,而且似乎运行良好。但是,基于此,我将文件上传的路径存储在实体中的单独属性中:

http://symfony.com/doc/master/cookbook/doctrine/file_uploads.html

所以,我需要某种方式让模板访问路径字段。我创建了一个这样的自定义 FileType 类:

<?php

namespace TechPeople\InvoiceBundle\Component\Form\Type;

use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;

use Symfony\Component\Form\Extension\Core\Type\FileType as SymfonyFileType;

class FileType extends SymfonyFileType {
    /**
     * {@inheritdoc}
     */
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars = array_replace($view->vars, array(
            'type'  => 'file',
            'value' => '',
            'path' => $options['path'],
        ));
    }
}

然后我将文件路径传递给表单构建器,如下所示:

<?php

namespace TechPeople\InvoiceBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class InvoiceType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        echo 'test';
        $builder
            ->add('month')
            ->add('year')
            ->add('expenses')
            ->add('due')
            ->add('paid')
            ->add('created')
            ->add('expense_amount', 'money')
            ->add('total_amount', 'money')
            ->add('attachment', 'file', array('path'=>$options['data']->getAttachmentPath()))
            ->add('vendor')
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'TechPeople\InvoiceBundle\Entity\Invoice'
        ));
    }

    public function getName()
    {
        return 'techpeople_invoicebundle_invoicetype';
    }
}

嗯,这看起来很时髦,但是我在加载表单时遇到了这个错误:

The option "path" does not exist. Known options are: "attr", "block_name", "by_reference", "cascade_validation", "compound", "constraints", "csrf_field_name", "csrf_protection", "csrf_provider", "data", "data_class", "disabled", "empty_data", "error_bubbling", "error_mapping", "extra_fields_message", "intention", "invalid_message", "invalid_message_parameters", "label", "label_attr", "mapped", "max_length", "pattern", "post_max_size_message", "property_path", "read_only", "required", "translation_domain", "trim", "validation_constraint", "validation_groups", "virtual"
500 Internal Server Error - InvalidOptionsException

所以,某处似乎有一个允许选项列表,但我找不到。此外,我不能 100% 确定 InvoiceType 中的 add() 方法是否将选项数组传递给 FileType 中的 buildView() 方法。我无法追踪这两件事之间的代码。

【问题讨论】:

标签: php forms file-upload symfony


【解决方案1】:

首先,一旦你创建了你的自定义类,你应该声明它(注册它)用作file 类型: http://symfony.com/doc/current/reference/dic_tags.html#form-type

<?php

namespace TechPeople\InvoiceBundle\Component\Form\Type;

use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;

use Symfony\Component\Form\Extension\Core\Type\FileType as SymfonyFileType;

class FileType extends SymfonyFileType 
{
/**
 * {@inheritdoc}
 */
public function buildView(FormView $view, FormInterface $form, array $options)
{
    $view->vars = array_replace($view->vars, array(
        'type'  => 'file',
        'value' => '',
        'path' => $options['path'],
    ));
}

/**
 * {@inheritdoc}
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'path' => null,
    ));
}

/**
 * {@inheritdoc}
 * 
 * POTENTIALLY declare it as child of file type.
 */
public function getParent()
{
    return 'file';
}
}

【讨论】:

  • 那么,setDefaultOptions 实际上设置了允许的选项吗?我认为这只是为其他地方定义的一组选项设置默认值。我试试看,谢谢。
  • 成功了。没有更多的错误。 ¡ 万分感谢!不确定 getParent() 方法的目的是什么。我的意思是我知道这个类扩展了(因此是真正的 FileType 的子类),但我不确定为什么需要这样说的方法。此外,getName() 方法仍将返回“文件”。看起来有点奇怪,就像是自己的父亲一样。我不知道,我想我只是无知。但如果你有时间的话,总是很高兴能少一些。
  • 我认为getParent主要用于表单类型扩展,所以不确定是否需要。
  • getParent 用于模板继承。表单 API 将通过此继承路径搜索潜在模板以呈现类型。可能类似于 my_type -> 集合 -> 表单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多