繁体   English   中英

Symfony2嵌入式表单+动态表单更新

[英]Symfony2 embedded forms + dynamic form update

我的表单中有一个下拉菜单,并且表单结构取决于其值。 我设法通过事件订阅者/侦听器类解决了“ form-update-issue”问题,在该类中,我试图根据下拉列表的值更新主表单。

主要问题是我必须根据数据库中保留的值来修改表单。 我的数据库架构:

我有4个表: ModelModelCategoryModelCategoryKeyModelParameter

  • ModelCategory 1--n Model 1--m ModelParameter
  • ModelCategory 1--n ModelCategoryKey
  • ModelCategoryKey 1-n ModelParameter

在用户从表单(基于模型实体的表单)下拉列表中选择ModelCategory之后,我必须使用ModelParamater行来更新表单,但是其数量和默认值取决于ModelCategory 1 – n ModelCategoryKey组件。

我试图在PRE_BIND事件期间将NEW ModelParameter实体附加到主Model实体(也设置其默认值),并且看起来工作正常,但是当我将带有“ collection”类型元素的“ parameters”添加到表单i得到下一个错误:

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

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

欢迎所有想法!

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

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

要么

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

其中“ factory”属性是FormFactoryInterface。 错误消息是相同的。

UPDATE2:

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

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

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) ;。 行,它似乎工作正常。 如果确实可行,我将做更多的工作并分享经验。

choice字段仅接受托管实体,因为该值在提交后设置为实体,并且表单仅发布实体ID,因此必须事先保存。

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

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

我在这里假设category_select是具有类别的选择字段,而parameter是具有其自身值的子形式,具体取决于您的参数结构。

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

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

  • 通过反面的加法器功能添加新创建的对象就足够了。 我不必致电所有者的二传手。
  • 反向方加法器函数必须进行修改,它调用拥有方的setter。
  • 反向加法器函数必须检查对象是否尚未在集合中。
  • 创建表单时,发生PRE_SET_DATA事件。 (因此在新实体中为空,而在旧实体中为空)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM