Symfony 2:在FormBuilder中访问数据库

9

我正在构建一个包含类别字段的表单。我需要一个选项列表来实现这一点,但我不知道如何使用数据库中存储的各个类别来填充该选项列表。

public function buildForm(FormBuilder $builder, array $options) {
  $builder->add('item', 'text', array('label' => 'Item'));
  $builder->add('category', 'choice', array(
    'choices'   => ???,
    'label' => 'Category'
  ));
}

我该如何从数据库获取分类信息?
(我无法在这个类中访问$this->getDoctrine()。)

2个回答

15

使用 entity 类型代替 choice 类型

$builder
  ->add('entity_property', 'entity', array(
    'class' => 'Namespace\\To\\Entity',
    'query_builder' => function(EntityRepository $repository) {
       return $repository->createQueryBuilder('q')
          ->where('q.a_field = yourvalue');
     }
));

编辑:

两种在查询中使用自定义参数的方法。在这两种情况下,参数都是从外部注入的,因此您的FormType不需要任何与会话或请求对象等相关的引用。

1- 将所需参数传递给构造函数

class TaskType extends AbstractType
{
    private $custom_value;

    public function __construct($custom_value) {
        $this->custom_value = $custom_value;
    }

    // ...
}

在你的 buildForm() 中,你必须将值复制到本地变量并使其对 query_builder 回调函数可用:

public function buildForm(/*...*/) {
   $my_custom_value = $this->custom_value;

   // ...
       'query_builder' => function(EntityRepository $repository) use ($my_custom_value) {
           return $repository->createQueryBuilder('q') 
               ->where('q.a_field = :my_custom_value')
               ->setParameter('my_custom_value', $my_custom_value);
       }

   // ...
}

2- 使用 buildForm 方法的 $options 参数。

首先,您需要通过覆盖 getDefaultOptions 来定义默认值:

public function getDefaultOptions(array $options)
{
    return array(
        'my_custom_value' => 'defaultvalue'
    );
}

你可以将其从控制器中作为 createForm 方法的第三个参数传递。

$this->createForm(new YourFormType(), $entity, array('my_custom_value' => 'custom_value'));

现在该值应该通过您的 buildForm 方法的 $options 参数可用。按照上述说明将其传递给回调函数。


谢谢,我也通过阅读相关帖子找到了答案^^不过还有一个问题,生成的选择列表似乎将实体的主键作为默认值,是否可以使用另一个属性来代替? - Yoot
我认为没有选项可以使用另一个属性作为值字段。文档中也没有关于此的提示(http://symfony.com/doc/2.0/reference/forms/types/entity.html)。解决方案可能是,在您的Type构造函数中传递自定义数组,然后再次使用choice类型。然后,您可以从控制器中使用自定义结构构建数组。 - hacksteak25
好的,谢谢。最后一个问题:我怎样可以在我的查询中使用动态参数(比如一些会话变量)? - Yoot
我编辑了我的回答。这里有两个你可以做的例子。 - hacksteak25

2

Symfony 2.1中的改动

现在你需要在setDefaultOptions方法中使用OptionsResolverInterface。以下是如果想要检索选项的代码(使用与已接受答案相同的示例):


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

public function buildForm(FormBuilderInterface $builder, array $options){

    parent::buildForm($builder, $options);

   $my_custom_value = $options[custom_value];

   // ...
       'query_builder' => function(EntityRepository $repository) use ($my_custom_value) {
           return $repository->createQueryBuilder('q') 
               ->where('q.a_field = :my_custom_value')
               ->setParameter('my_custom_value', $my_custom_value);
       }

   // ...

}
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'my_custom_value' => 'defaultvalue'
        ));
    }

您仍可以以相同的方式传递选项:
$this->createForm(new YourFormType(), $entity, array('my_custom_value' => 'custom_value'));

原来的方法似乎仍然有效,但感谢您发布这个更具有Symfonic风格的方法! - Acyra
但是如果我还没有创建存储库呢? - karmicdice

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