在 Typo3 中,通过 Extension Builder 设置模型结构,如何编辑通过 1:n 连接到父模型的子模型的值?

问题描述

我正在开发一个使用 Typo3 9.5.14 和 Extension Builder 9.10.2 的项目。我有一个与“标签”模型具有 1:n 关系的“提供者”模型。它看起来像这样: Extension Builder provider-label relation

我的目标:通过 HTML 表单,我想编辑连接到特定提供程序的标签的值。目前我的实现如下所示。

我有一个具有“companyProfileSaveAction”方法的控制器。该方法有效并允许我设置提供者模型的属性。它看起来像这样:

public function companyProfileSaveAction(Provider $provider)
{
    $persistenceManager = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class);
    
    if ($provider->getUid()) {
        $this->providerRepository->update($provider);
    } else {
        $this->providerRepository->add($provider);
    }

    $persistenceManager->persistAll();

    $this->redirect('companyProfilePage',null,['provider' => $provider,'saved' => true]);
}

这里提到的 providerRepository 扩展了 \TYPO3\CMS\Extbase\Persistence\Repository。函数“update”和“add”来自这个继承。

现在我尝试使用此功能添加或编辑提供者的标签,这些标签通过如上所述的 1:n 关系连接。我通过 html 表单发送数据。数据基本上是这样的:

tx_my_extension[provider][labels][0][name]: label 1
tx_my_extension[[provider][labels][0][text]: description 1
tx_my_extension[[provider][labels][1][name]: label 2
tx_my_extension[[provider][labels][1][text]: description 2
tx_my_extension[[provider][labels][2][name]: label 3
tx__my_extension[[provider][labels][2][text]: description 3

这也有效,标签被创建并连接到提供者。但是现在,举个例子,假设我想像这样编辑我的标签

tx_my_extension[provider][labels][0][name]: label 1 edited
tx_my_extension[[provider][labels][0][text]: description 1
tx_my_extension[[provider][labels][1][name]: label 2 edited
tx_my_extension[[provider][labels][1][text]: description 2
tx_my_extension[[provider][labels][2][name]: label 3 edited
tx__my_extension[[provider][labels][2][text]: description 3

当我这样发送时,旧的三个标签与我的提供商完全断开连接,并创建了三个新标签。随着时间的推移,这会用许多断开连接的标签填充我的数据库,这些标签没有任何用途。我如何编辑现有的标签,而不是每次保存表单时都创建新标签

解决方法

我已经有一段时间没有弄乱 TYPO3 的这些部分了,但是:

您是否尝试添加 __identity 虚拟帖子字段,例如tx_my_extension[provider][labels][0][__identity]: 123 其中值是相关对象的 UID?

这应该使属性映射器在将值映射到属性之前获取这个对象,这反过来应该意味着您的根实体仍然与子实体相关,并且子实体被标记为“脏”,然后被持久化。