4

我正在构建一个从“EntityType”扩展的自定义表单字段类型。我总是想根据传递的选项返回元素的子集。

在我的类型中:

$builder->add('Categories','choice_category', array('code'=> 'CAT1', 'multiple'=> true))   ;

我已将choice_category 声明为服务。工作正常!

  bt.form.type.category:
  class: My\MBundle\Form\Type\CategoryType
  tags:
      - { name: form.type, alias: choice_category }

在 CategoryChoiceType.php

public function setDefaultOptions(OptionsResolverInterface $resolver)
{

    $resolver->setDefaults(
        array(
            'class'=> 'CmComunBundle:Comun\Nomenclador',
            'code'          => null,                
        )
    );
}


public function getParent()
{
    return 'entity';
}

我正在考虑使用 query_builder 选项,但我不知道如何将代码选项传递给 setDefaultOptions 方法,我在这里无法访问 $options 数组。

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
        $resolver->setDefaults(
        array(
            'class'=> 'CmComunBundle:Comun\Nomenclador',
            'code'          => null,
            'query_builder' => function(\Doctrine\ORM\EntityRepository $er) use ($options['code']) {
               return $er->createQueryBuilder('c')
                    ->where('c.parent_code = :code')
                    ->orderBy('c.name', 'ASC')
                    ->setParameter('code', $options['code']);;
            }
        )
    );
);
4

2 回答 2

12

您几乎做对了,但是您需要使用以下特殊语法使“query_builder”依赖于另一个选项“code”:

use Symfony\Component\OptionsResolver\Options;

$resolver->setDefaults(array(
    'query_builder' => function (Options $options) {
        // return default value of the "query_builder" option
        // you can access $options['code'] here
    },
));

所以在你的具体例子中:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'class' => 'CmComunBundle:Comun\Nomenclador',
        'code' => null,
        'query_builder' => function (Options $options) {
            return function(EntityRepository $er) use ($options) {
                return $er->createQueryBuilder('c')
                    ->where('c.parent_code = :code')
                    ->orderBy('c.name', 'ASC')
                    ->setParameter('code', $options['code']);;
            };
        },
    ));
}

这也记录在OptionsResolver README中。

于 2012-12-09T15:40:43.573 回答
2

您可以通过依赖注入将code值传递给__construct并将其存储以供以后在setDefaultOptions方法中使用。

class CategoryType{
    ...
    private $code;
    ...
    public function __construct($code){
        $this->code = $code
    }
    ...
    public function setDefaultOptions(OptionsResolverInterface $resolver){
        $code = $this->code;
        $resolver->setDefaults(
        array(
            'class'=> 'CmComunBundle:Comun\Nomenclador',
            'code'          => null,
            'query_builder' => function(\Doctrine\ORM\EntityRepository $er) use ($code) {
                return $er->createQueryBuilder('c')
                                ->where('c.parent_code = :code')
                                ->orderBy('c.name', 'ASC')
                                ->setParameter('code', $code);
            })
        );
    );
}

并在您的配置中:

bt.form.type.category:
    class: My\MBundle\Form\Type\CategoryType
    tags:
        arguments:
                - some_code_value
        - { name: form.type, alias: choice_category }

现在,我还没有尝试过,但感觉它应该以这种方式工作;)

希望这可以帮助!

于 2012-12-06T17:37:48.813 回答