我花了很长时间才能正确获得标题,而我还没有写这个问题:/
这里:我的菜单是从实体加载的。为了允许用户将菜单转换为多种语言,我创建了一个与Menu
通过ManyToOne
关联关联的Menu
实体和LocalizedMenu
实体。
遵循此简短指南,我将与LocalizedMenu->locale
字段的关联索引。这样可以确保数据库中每个语言环境只有一个LocalizedMenu
,并且该学说覆盖了现有的语言。
这就是外观:
/**
* @ORMEntity(repositoryClass="AppRepositoryMenuRepository")
*/
class Menu
{
/**
* @Groups({"menu"})
* @ORMId
* @ORMColumn(type="integer")
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
// ...
/**
* References translated menus.
* @Groups({"localized_menus"})
*
* @ORMOneToMany(
* targetEntity="LocalizedMenu"
* ,mappedBy="parentMenu"
* ,indexBy="locale"
* ,cascade={"persist", "remove"}
* )
* @ORMOrderBy({"locale" = "ASC"})
*/
private $localizedMenus;
// ...
public function getLocalizedMenu($locale) {
if (!isset($this->localizedMenus[$locale])) {
return new LocalizedMenu($locale, $this);
}
return $this->localizedMenus[$locale];
}
public function addLocalizedMenu($localizedMenu): self
{
$this->localizedMenus[$localizedMenu->getLocale()] = $localizedMenu;
return $this;
}
}
LocalizedMenu
是一个持有用户翻译菜单字段的实体:
/**
* @ORMEntity(repositoryClass="AppRepositoryLocalizedMenuRepository")
*/
class LocalizedMenu
{
public function __construct($locale, $menu) {
$this->locale = $locale;
$this->parentMenu = $menu;
$this->parentMenu->addLocalizedMenu($this);
}
// region FIELDS
/**
* @Groups({"localized_menu", "localized_menus"})
* @ORMId
* @ORMColumn(type="integer")
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @Groups({"localized_menu", "localized_menus"})
* @var $locale string
* @ORMColumn(
* type = "string"
* ,unique = true
* )
*/
private $locale = "";
/**
* @Groups({"localized_menu", "localized_menus"})
* @ORMColumn(
* type = "string",
* length = 75
* )
*/
private $title = "";
/**
* @Groups({"localized_menu", "localized_menus"})
* @var $description string Extra description for this menu item
* @ORMColumn(
* type = "text",
* name = "description"
* )
*/
private $description = "";
/**
* @Groups({"localized_menu", "localized_menus"})
* @ORMColumn(
* type = "datetime",
* name = "creation_date"
* )
* @AssertDateTime()
*/
private $creationDate;
/**
* @Groups({"localized_menu", "localized_menus"})
* @ORMColumn(
* type = "datetime",
* name = "edit_date"
* )
* @AssertDateTime()
*/
private $editDate;
/**
* @Groups({"localized_menu", "localized_menus"})
* @ORMColumn(type="text")
* @AssertNotBlank(
* message = "Een menu item is een pagina die inhoud nodig heeft, vergeet dit niet"
* )
*/
private $content = "";
/**
* @var $parentMenu Menu Parent menu for this localized menu
*
* @Groups({"localized_menu", "localized_parent_menu"})
* @ORMManyToOne(
* targetEntity="Menu",
* inversedBy="localizedMenus"
* )
*/
private $parentMenu;
}
要将所有这些都带给用户进行编辑,我创建了一个MenyType
表格:
$builder
->add('localizedMenus', CollectionType::class, array(
'entry_type' => LocalizedMenuType::class,
"entry_options" => [
"choice_locale" => $options["choice_locale"]
],
'allow_add' => true,
'allow_delete' => true,
'required' => false
))
和 LocalizedMenuType
表格:
$builder
->add('title', TextType::class, array(
'label' => 'Titel',
'trim' => true
))
->add('description', TextareaType::class, array(
'label' => 'Omschrijving',
'trim' => true
))
->add('content', TextareaType::class, array(
'label' => 'Inhoud',
'trim' => true,
'attr' => array('class' => 'tinymce'),
'data' => " "
))
->add('locale', LocaleType::class, array(
"choice_translation_locale" => $options["choice_locale"]
))
;
i"思考"此逻辑是正确的,但是使用JavaScript创建新的LocalizedMenu
表单后,我会得到此错误:
太少的参数无法函数app entity entainizedMenu :: __ construct(), 0通过 /users/robbievercammen/projects/web/base/vendor/symfony/form/form/extension/core/type/formtype.php 在第136行,正好2个预期
我如何使自己的表格优雅地使用逻辑?
编辑 - 真实问题
错误消息不是这里的真正错误。正如我之前说的,如果我删除了构造函数参数,它确实将记录保存到数据库中。即让学说使用协会将新的LocalizedMenu
记录与Menu
记录相关联。这就是数据库中的外观:
Menu
|id| //...
| 7| //...
LocalizedMenu
| id | locale | title | description | creation_date | edit_date
| content | parent_menu_id |
----
| 4 | nl | Contact | Contact | 2019-02-21 14:02:47 | 2019-02-21 14:02:47 |
Contact | NULL |
问题是LocalizedMenu -> parent_menu_id
是零。由于某种原因,我的设置不会为父菜单生成ID。下次从数据库获取菜单时,$menu->getLocalizedMenus()
返回一个空数组,因为它们不正常。
遵循我提到的指南,这似乎是我告诉学说 $localizedMenu -> locale
您的LocalizedMenu
构造函数需要两个参数-$locale
和$menu
。当Symfony为您的新提交的数据实例化新的LocalizedMenu
实例时,它会直接进行new LocalizedMenu()
填充其数据。
如果您需要自定义形式中的新/动态内容创建对象的方式(例如,当您具有constructor参数时),则必须在LocalizedMenuType
类上设置empty_data
选项。
请参阅https://symfony.com/doc/current/form/use_empty_data.html有关更多信息。
您的LocalizedMenu
构造函数参数之一是菜单实例。此菜单实例将需要作为必需的选项传递给您的LocalizedMenuType
。
class LocalizedMenuType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setRequired('menu');
$resolver->setAllowedTypes('menu', Menu::class);
$resolver->setDefault('empty_data', function (Options $options) {
return new LocalizedMenu($options['choice_locale'], $options['menu']);
});
}
}