简体   繁体   English

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

[英]Symfony2 embedded forms + dynamic form update

I have a dropdown menu in my form and the form structure depends on its value. 我的表单中有一个下拉菜单,并且表单结构取决于其值。 I have managed to solve the "form-update-issue" with event subscriber/listener class, where i am trying to update the main form according to dropdown's value. 我设法通过事件订阅者/侦听器类解决了“ form-update-issue”问题,在该类中,我试图根据下拉列表的值更新主表单。

The main problem is that i have to modify the form from values that persisted in the database. 主要问题是我必须根据数据库中保留的值来修改表单。 My DB schema: 我的数据库架构:

I have 4 table: Model , ModelCategory , ModelCategoryKey , ModelParameter . 我有4个表: ModelModelCategoryModelCategoryKeyModelParameter

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

After the user choose a ModelCategory from the form's (form based on Model entity) dropdown i have to update the form with ModelParamater rows, but it's number and default values depends on ModelCategory 1--n ModelCategoryKey assocaiton. 在用户从表单(基于模型实体的表单)下拉列表中选择ModelCategory之后,我必须使用ModelParamater行来更新表单,但是其数量和默认值取决于ModelCategory 1 – n ModelCategoryKey组件。

I've tried to attach NEW ModelParameter entities to the main Model entity during the PRE_BIND event (also set their default values) and it seems working fine, but when i add the 'parameters' with a 'collection' typed element to the form i get the next error: 我试图在PRE_BIND事件期间将NEW ModelParameter实体附加到主Model实体(也设置其默认值),并且看起来工作正常,但是当我将带有“ collection”类型元素的“ parameters”添加到表单i得到下一个错误:

Entities passed to the choice field must be managed. 传递给选择字段的实体必须进行管理。 Maybe persist them in the entity manager? 也许将它们保留在实体经理中?

Clearly my entities can't be (and shouldn't be) persisted at this time. 显然,此时我的实体不能(也不应该)持久。

All ideas are welcome! 欢迎所有想法!

UPDATE: Modifying the form after preSubmit/preBind: 更新:在preSubmit / preBind之后修改表单:

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

OR 要么

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

where the 'factory' attribute is a FormFactoryInterface. 其中“ factory”属性是FormFactoryInterface。 The error message is the same. 错误消息是相同的。

UPDATE2: UPDATE2:

Further investigation proved, that if i don't add "default" entities to the assocation. 进一步的调查证明,如果我不向关联添加“默认”实体。 Then it works without error. 然后它可以正常工作。

Here is the source of my form modifying method: 这是我的表单修改方法的来源:

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
                ))
    );

}

SEEMS TO BE SOLVED BY I have just commented out the $param->setModel($entity); 要解决的问题我刚刚注释掉$ param-> setModel($ entity) ;。 line and it seems to be working fine. 行,它似乎工作正常。 I will work this out more and will share the experience, if it realy works. 如果确实可行,我将做更多的工作并分享经验。

choice field accepts only managed entities, as the value is set to the entity after submit, and form posts only entities ID, so it must be saved beforehand. choice字段仅接受托管实体,因为该值在提交后设置为实体,并且表单仅发布实体ID,因此必须事先保存。

You don't need choice field - you need collection of parameter subforms. 您不需要选择字段-您需要参数子窗体的集合。

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

I'm assuming here that category_select is choice field with categories and parameter is subform with it's own values, depending on your parameter structure. 我在这里假设category_select是具有类别的选择字段,而parameter是具有其自身值的子形式,具体取决于您的参数结构。

When you have category in your controller, you can bind the newly created entity with added Parameter entities with their key set, depending on ModelCategoryKey. 当控制器中具有类别时,可以将新创建​​的实体与添加的Parameter实体及其key集绑定,具体取决于ModelCategoryKey。

I've managed to solve my problem, so here it is what i've found out: 我已经设法解决了我的问题,所以这就是我发现的内容:

  • It is enough to add the newly created object by the adder function of the inverse side. 通过反面的加法器功能添加新创建的对象就足够了。 I don't have to call the owning side's setter. 我不必致电所有者的二传手。
  • Inverse side adder function must be modified, that it calls the owning side's setter. 反向方加法器函数必须进行修改,它调用拥有方的setter。
  • Inverse side adder function must check if the object is not in the collection already. 反向加法器函数必须检查对象是否尚未在集合中。
  • PRE_SET_DATA event happens, when the form is created. 创建表单时,发生PRE_SET_DATA事件。 (so in new entities it is empty, and in old ones it is filled) (因此在新实体中为空,而在旧实体中为空)

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

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