2

我的表单中有一个下拉菜单,表单结构取决于它的值。我已经设法用事件订阅者/侦听器类解决了“表单更新问题”,我试图根据下拉列表的值更新主表单。

主要问题是我必须从数据库中持久的值修改表单。我的数据库架构:

我有 4 个表:ModelModelCategoryModelCategoryKeyModelParameter

  • ModelCategory 1--n Model 1--m ModelParameter
  • ModelCategory 1--n ModelCategoryKey
  • ModelCategoryKey 1--n 模型参数

在用户从表单(基于模型实体的表单)下拉列表中选择模型类别后,我必须使用 ModelParamater 行更新表单,但它的数量和默认值取决于 ModelCategory 1--n ModelCategoryKey assocaiton。

我尝试在 PRE_BIND 事件期间将 NEW ModelParameter 实体附加到主模型实体(也设置它们的默认值),它似乎工作正常,但是当我将带有“集合”类型元素的“参数”添加到表单中时得到下一个错误:

必须管理传递给选择字段的实体。也许将它们保留在实体管理器中?

显然,我的实体此时不能(也不应该)持久化。

欢迎所有想法!

更新: 在 preSubmit/preBind 之后修改表单:

$form->add('parameters','collection',array(
    'type' => new ModelParameterType(),         
));

或者

$form->add(
            $this->factory->createNamed('parameters','collection',null,
                array(
                    'type' => new ModelParameterType()
                    ))
        );

其中“工厂”属性是 FormFactoryInterface。错误信息是一样的。

更新2:

进一步调查证明,如果我不将“默认”实体添加到关联中。然后它可以正常工作。

这是我的表单修改方法的来源:

public function preSubmit(FormEvent $event) {
    $form = $event->getForm();  
    $id = $event->getData()['modelCategory'];       
    $entity = $form->getData();
    $categoryKeys = $this->em->getRepository('MyBundle:ModelCategoryKey')->findByModelCategory(
        $this->em->getReference('MyBundle:modelCategory',$id)
    );      
    foreach ($categoryKeys as $key) {
        $param = new ModelParameter();
        $param->setModel($entity);
        $param->setKey($key); 
        $entity->addParameter($param);
    }

    $form->add(
        $this->factory->createNamed('parameters','collection',null,
            array(
                'type' => new ModelParameterType(),
                'allow_add' => true,
                'cascade_validation' => true
                ))
    );

}

似乎可以解决我刚刚注释掉了 $param->setModel($entity) ; 线,它似乎工作正常。如果它真的有效,我会更多地解决这个问题并分享经验。

4

2 回答 2

0

choice字段只接受托管实体,因为值是提交后设置的实体,而表单只发布实体ID,所以必须事先保存。

您不需要选择字段 - 您需要参数子表单的集合。

$formBuilder
    ->add('category', 'category_select')
    ->add('parameters', 'collection', array('type' => 'parameter'))
;

我在这里假设这category_select是具有类别的选择字段,并且parameter是具有自己的值的子表单,具体取决于您的参数结构。

当您的控制器中有类别时,您可以将新创建​​的实体与添加的参数实体及其key集合绑定,具体取决于 ModelCategoryKey。

于 2013-09-06T21:16:56.523 回答
0

我已经设法解决了我的问题,所以这就是我发现的:

  • 通过反方的adder函数将新创建的对象相加就足够了。我不必打电话给拥有方的二传手。
  • 必须修改反向加法器函数,它调用拥有方的设置器。
  • 反向加法器函数必须检查对象是否不在集合中。
  • PRE_SET_DATA 事件在创建表单时发生。(所以在新实体中它是空的,而在旧实体中它是填充的)
于 2013-09-08T20:47:11.830 回答