Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Symfony2:自定义表单类型的动态默认值?_Symfony - Fatal编程技术网

Symfony2:自定义表单类型的动态默认值?

Symfony2:自定义表单类型的动态默认值?,symfony,Symfony,我使用实体表单类型提供表单中位置实体的列表。我经常使用它(每个都有相同的“设置”代码来定制),因此我决定从中创建一个自定义表单类型,以便更好地重用 以下是当前的表单类型: class PositionType extends AbstractType { private $om; public function __construct(ObjectManager $om, $mode) { $this->om = $om; } p

我使用
实体
表单类型提供表单中
位置
实体的列表。我经常使用它(每个都有相同的“设置”代码来定制),因此我决定从中创建一个自定义表单类型,以便更好地重用

以下是当前的表单类型:

class PositionType extends AbstractType
{
    private $om;

    public function __construct(ObjectManager $om, $mode)
    {
        $this->om = $om;
    }

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

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        // I need to pass "mode" as an option when building the form.
        $mode = ???
        $query_builder = function (EntityRepository $em) use ($mode) {
            // Limit the positions returned based on the editing mode
            return $em
                ->createQueryBuilder('Position')
                ->orderBy('Position.name')
                ->leftJoin('Position.type', 'Type')
                ->andWhere('Type.id IN (:ids)')
                ->setParameter('ids', Type::typesForMode($mode))
            ;
        };

        $resolver
            ->setRequired(array('mode'))
            ->setDefaults(array(
                'label' => 'Position',
                'class' => 'AcmeBundle:Position',
                'property' => 'name',
                'query_builder' => $query_builder,
                'empty_value' => '',
                'empty_data' => null,
                'constraints' => array(
                    new NotBlank(),
                ),
            ))
        ;
    }

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

    public function getName()
    {
        return 'position';
    }
}
不要担心查询生成器中的细节,这并不重要。重要的是我正在尝试在查询生成器中使用表单类型选项

我该怎么做?问题是我不能在
setDefaultOptions
中使用
$mode
(我想要传递的选项来改变查询生成器)


我开始寻找一种从
buildForm
内部设置查询生成器的方法,但我不确定我是否可以这样做。

您可以使用表单选项将变量传递到表单生成器。
例如在控制器中

public function createAction()
{
    $form = $this->formFactory->create('client', $client, array('name' => 'create'));

    return $this->template->renderResponse('bundle:add.html.twig', array('form' => $form->createView()));
}
在你的形式类型

class PositionType extends AbstractType
{
    private $mode;

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $this->mode = $options['name'];
    }


    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        // I need to pass "mode" as an option when building the form.
        $mode = ???
        $query_builder = function (EntityRepository $em) use ($this->mode) {
            // Limit the positions returned based on the editing mode
            return $em
                ->createQueryBuilder('Position')
                ->orderBy('Position.name')
                ->leftJoin('Position.type', 'Type')
                ->andWhere('Type.id IN (:ids)')
                ->setParameter('ids', Type::typesForMode($mode))
            ;
        };

        $resolver
            ->setRequired(array('mode'))
            ->setDefaults(array(
                'label' => 'Position',
                'class' => 'AcmeBundle:Position',
                'property' => 'name',
                'query_builder' => $query_builder,
                'empty_value' => '',
                'empty_data' => null,
                'constraints' => array(
                    new NotBlank(),
                ),
            ))
        ;
    }
}

这是相当容易实现的。您可以构建一个依赖于另一个选项的选项

基本上你会做:

$resolver
    ->setRequired(array('mode', 'em')) // "em" for EntityManager as well
    ->setDefaults(array(
        'label' => 'Position',
        'class' => 'AcmeBundle:Position',
        'property' => 'name',
        #####################################################
        'query_builder' => function(Options $options){
            // Obviously you will need to pass the EntityManager
            $em = $options['em'];

            // Limit the positions returned based on the editing mode
            return $em
                ->createQueryBuilder('Position')
                ->orderBy('Position.name')
                ->leftJoin('Position.type', 'Type')
                ->andWhere('Type.id IN (:ids)')
                ->setParameter('ids', Type::typesForMode($options['mode'])) // 
            ;
        },
        ####################################
        'empty_value' => '',
        'empty_data' => null,
        'constraints' => array(
            new NotBlank(),
        ),
    ))
;

这只是
选项解析器
功能的粗略表示。希望它有帮助:)

但是在
buildForm
之前没有调用
setDefaultOptions
吗?@Brian您是对的,setDefaultOptions确实会首先被调用。在构造函数中传递变量对您来说是一个选项吗?很好,正是我所需要的。谢谢。不过,我没有传递实体管理器,而是返回了最初完成的可调用函数,它从Symfony传递给管理器