Doctrine orm 打印新分配的实体';在使用CollectionType提交表单后立即使用s id 不久说

Doctrine orm 打印新分配的实体';在使用CollectionType提交表单后立即使用s id 不久说,doctrine-orm,symfony-forms,symfony,Doctrine Orm,Symfony Forms,Symfony,在提交新项目时,Symfony会处理POST数据,但新持久化的项目没有在其相应的隐藏字段值属性中填充其id,而是缺少值属性 手术: 我已经实现了一些添加/编辑/删除功能,使用户可以使用管理一个“城市”实体池。 添加新城市时: 我确保每个现有条目都有一个隐藏字段,其中包含实体的id(pk)以及可编辑的常规属性,以便正确更新现有实例 提交表格时,数据可用[ok] 持续循环和后续刷新成功更新数据库[确定] 表单将使用新添加的城市再次呈现 除了任何新提交的城市的隐藏字段缺少«value»属性之外,所

在提交新项目时,Symfony会处理POST数据,但新持久化的项目没有在其相应的隐藏字段值属性中填充其id,而是缺少值属性

手术: 我已经实现了一些添加/编辑/删除功能,使用户可以使用管理一个“城市”实体池。
添加新城市时:

  • 我确保每个现有条目都有一个隐藏字段,其中包含实体的id(pk)以及可编辑的常规属性,以便正确更新现有实例
  • 提交表格时,数据可用[ok]
  • 持续循环和后续刷新成功更新数据库[确定]
  • 表单将使用新添加的城市再次呈现
除了任何新提交的城市的隐藏字段缺少«value»属性之外,所有这些都正常工作

我读的东西像
在flush之后立即访问对象getter将返回相应的最新属性。新插入的记录ID已填充

所以我希望Doctrine在刷新时更新新保存的城市对象,但看起来什么都没有发生表单似乎没有意识到新的插入。这是因为表单数据在处理请求后具有不变性吗? 注意:至少,当重新加载页面时(在不发布两次数据的情况下到达相同的URL),隐藏字段最终会打印其属性值和相应实体的id

有人能帮我找出这里需要做什么,以便在提交后立即正确呈现(新插入项的)隐藏字段(使用包含预期实体id的«value»属性)

控制器…

关联模板

{{#…}
{{form_start(form)}}
{集合%中的项的%s}
{{form_widget(item)}
{%endfor%}

{{'按钮添加标题'| trans}}

提交

{{form_end(form)}}
这很清楚,谢谢

编辑 在集合的
条目\u选项中,
by\u reference
设置为true

我做过的测试表明:它只在那里有影响。如果为True,则可以更新数据库中的相应(现有)记录。另一方面,false会阻止进行映射,从而导致数据库中出现重复条目。
在收藏本身上设置
(按_reference设置)
似乎根本没有任何作用。
也就是说,新记录实际上是持久的,但是修改这个新创建的元素会导致随机行为(由于允许删除而被删除,发布了重复条目)。仍然开发工具DOM树不显示隐藏字段的
属性,导航器源快捷键Ctrl+u也不显示。一旦发出新的GET请求,Value属性就会神奇地出现。 这里肯定有我不明白的事情。
:/


最后,我发现确保表单正确填充隐藏字段的唯一方法是命令
$this->redirect($this->generateUrl($_-route))
after
flush()

查看文档的最后一个段落–它特别是关于CollectionType的。这可能与您的问题无关,但您正在控制器中的CollectionType上手动重新实现
'by_reference'=>true
的语义。@Lumen感谢您抽出时间,我已经编辑了我的线程。
<?php
// ...
/**
 * @Route("/cities", name="admin_config_cities")
 */
public function configureCitiesAction(Request $request)
{
    # Retrieving existing cities
    $em = $this->getDoctrine()->getManager();
    $cities = $em->getRepository('AppBundle:City')->findAll();

    # Associate cities ids with corresponding objects
    $sorted = [];
    array_walk($cities, function ($value, $key) use (&$sorted) {
        $sorted[ $value->getId() ] = $value;
    });

    # Initialize form
    $citiesForm = $this->createForm(
        CollectionType::class,
        $cities,
        [
            'entry_type' => CityType::class,
            'allow_add' => true,
            'allow_delete' => true,
            'prototype' => true,
            # I thought "mapped" option would do the trick.
            # worse, seems to do nothing
            'mapped' => true,
            'label' => false,
            'entry_options'  => [
                'label' => false,
                'by_reference'=>true
            ]
        ]
    );
    if ($request->isMethod('POST')) {
        $citiesForm->handleRequest($request);
        if ($citiesForm->isValid()){
            # Persist any submitted datas
            foreach( $citiesForm->getData() as $city ){
                $id = $city->getId();
                if ($id && array_key_exists($id,$sorted)) {
                    unset($sorted[$id]);
                }
                $em->persist($city);
            }
            # Remove discared cities
            foreach( $sorted as $removed ){
                $em->remove($removed);
            }
            $em->flush();
        }
    }
    # TODO: find the way to make newly added cities to be rendered
    # along with their ID available inside an hidden field's attribute
    # right after submission (without the need of a refresh)
    return $this->render('AppBundle:admin:config/cities.html.twig', [
        'form' => $citiesForm->createView()
    ]);
}
//…
$builder->add( 'id', HiddenType::class, [ 'required'=>false ])
//…
{# … #}
{{ form_start(form) }}
    <div data-prototype="{{ form_widget(collection.vars.prototype)|e }}">
        {% for item in collection %}
            {{ form_widget(item) }}
        {% endfor %}
        <p>
            <a class="btn btn-default btn-sm" title="{{ 'button-add-title'|trans }}">{{ 'button-add-caption'|trans }}</a>
        </p>
    </div>
    <p class="text-right">
        <button type="submit">Submit</button>
    </p>
{{ form_end(form) }}