【问题标题】:How do I send "extra" data to a Symfony 3.2.x form using FormBuilder?如何使用 FormBuilder 将“额外”数据发送到 Symfony 3.2.x 表单?
【发布时间】:2017-04-05 20:15:19
【问题描述】:

我在 Symfony 3.2.7 控制器中有以下方法:

public function updateAction(Request $request)
{
    $em        = $this->getDoctrine()->getManager();
    // this is the original entity without modified values
    $entity    = $em->getRepository('QuoteBundle:Quote')->find($request->query->get('id'));

    // the entity passed to the form has the values modified coming from the request    
    $form = $this->createForm(CFProgramLevelQuoteType::class, $entity);
    ...
}

这是形式:

class CFProgramLevelQuoteType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('CFProgramLevel', EntityType::class, [
                'class'         => 'QuoteBundle:CFProgramLevel',
                'choice_label'  => 'description',
                'placeholder'   => 'Please select a program',
            ]);
    }
    ...
}

我将使用查询生成器过滤来自QuoteBundle:CFProgramLevel 的一些值,因此我需要从$entity 获取未修改的ID 并将其发送到表单。这是我目前想到的解决方案:

public function updateAction(Request $request)
{
    $em        = $this->getDoctrine()->getManager();
    $entity    = $em->getRepository('QuoteBundle:Quote')->find($request->query->get('id'));
    $entity_id = $entity->getCfProgramLevel()->getcfProgramLevelId();   
    $form = $this->createForm(CFProgramLevelQuoteType::class, $entity);
    ...
}

但是我如何将 entity_id 传递给表单并在那里使用它?如果有更好的方法来实现这一点,我愿意听取想法。我在 Google 中找不到任何有用的信息,因此不胜感激。

更新

尝试以下答案中提供的解决方案我也无法正常工作:

// controller
$form = $this->createForm(CFProgramLevelQuoteType::class, $entity, ['entity_id' => $entity_id]);

// form
public function buildForm(FormBuilderInterface $builder, array $options)
{
    dump($options);
    die();
    ...
}

public function setDefaultOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(['data_class' => Quote::class, 'entity_id' => null]);
    $resolver->setRequired('entity_id');
}

选项“entity_id”不存在。定义的选项是:“动作”, “allow_extra_fields”、“attr”、“auto_initialize”、“block_name”、 “by_reference”、“compound”、“constraints”、“csrf_field_name”、 “csrf_message”、“csrf_protection”、“csrf_token_id”、 “csrf_token_manager”、“数据”、“data_class”、“禁用”、“empty_data”、 “error_bubbling”、“error_mapping”、“extra_fields_message”、 “inherit_data”、“invalid_message”、“invalid_message_parameters”、 “标签”,“标签属性”,“标签格式”,“映射”,“方法”, “post_max_size_message”、“property_path”、“必需”、 “translation_domain”、“trim”、“upload_max_size_message”、 “验证组”。

【问题讨论】:

  • 在这种情况下可以尝试表单实体查询生成器:symfony.com/doc/current/reference/forms/types/…
  • @AndrewNolan 我不知道这对这里有什么帮助....
  • 所以你想在更新前取原来的getcfProgramLevelId,并有一个选择字段,其中包含基于getcfProgramLevelId值的数据库过滤结果?

标签: php symfony symfony-forms


【解决方案1】:

您可以为表单类型创建自己的自定义选项,如 http://symfony.com/doc/current/form/create_custom_field_type.html#defining-the-field-type 中所述

class CFProgramLevelQuoteType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        //$options['entity_id'] contains your id
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setRequired('entity_id');
    }
}

传递 entity_id:

$form = $this->createForm(CFProgramLevelQuoteType::class, $entity, [
    'entity_id' => $entity_id
]);

【讨论】:

  • 这对我不起作用The option "entity_id" does not exist. Defined options are ...
  • 你的方法 setDefaultOptions 甚至没有被调用,因为它从 symfony 2.7 开始就被弃用了。您必须使用 configureOptions 方法。请仔细检查代码symfony.com/blog/…
【解决方案2】:

这是一个完整的示例(也与@striker 非常相似)。如果没有拼写错误,请仔细检查。否则试试php bin/console cache:clear

控制器动作:

public function testAction(Request $request)
{
    $form = $this->createForm(TestType::class, null, [
        'option1' => 6
    ]);
    return $this->render('default/test.html.twig',[
        'form' => $form->createView()
    ]);
}

TestType.php:

class TestType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('test', IntegerType::class, [
            'data' => $options['option1']
        ]);
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setRequired('option1');
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'appbundle_test';
    }
}

【讨论】:

    【解决方案3】:

    要将额外数据传递给表单,您可以使用OptionsResolver::setDefined

    // App\Form\SomeFormType
    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefined('foo');
    }
    

    您可以像这样在 Controller 中传递数据:

    // Controller
    $this->createForm(SomeFormType::class, $entity, ['foo' => $data]);
    

    要使用传递的数据,只需访问定义的键:

    // App\Form\SomeFormType
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        // $options['foo']
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-07
      • 2014-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多