EasyAdmin 集合字段
此字段显示对象集合,通常通过渲染嵌入式表单列表来实现。
在表单页面(编辑和新建)中,它看起来像这样

当您单击任何列表项时,其内容将被展开,您可以访问其嵌入式表单

基本信息
- PHP 类:
EasyCorp
\Bundle \EasyAdminBundle \Field \CollectionField - Doctrine DBAL 类型 用于存储此值:此字段与 Doctrine 关联相关,因此间接使用
integer
,guid
或您用于存储关联实体 ID 的任何其他类型 - Symfony 表单类型 用于渲染字段: CollectionType
渲染为:
1 2
<!-- when loading the page this is transformed into a dynamic list of embedded forms --> <ul> ... </ul>
前提条件
正如 Symfony CollectionType 选项的文档 中所解释的那样,allowAdd
和 allowDelete
选项要求您的实体定义一些具有非常特定名称的特殊方法。否则,在后端创建或更新实体集合项时,更改将不会被持久化。
考虑一个 BlogPost
实体,它定义了与 Comment
实体的一对多关系以及与 Tag
实体的多对多关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
// ...
class BlogPost
{
// ...
#[ORM\OneToMany(targetEntity: Comment::class, mappedBy: 'post', orphanRemoval: true, cascade: ['persist'])]
private Collection $comments;
#[ORM\ManyToMany(targetEntity: Tag::class, cascade: ['persist'])]
#[ORM\JoinTable(name: 'my_app_blogpost_tag')]
private Collection $tags;
}
为了添加/删除评论或标签,您必须定义名为 add<Related Entity Singular Name>()
和 remove<Related Entity Singular Name>()
的“adder”和“remover”方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
class BlogPost
{
// ...
public function addComment(Comment $comment): void
{
$comment->setBlogPost($this);
if (!$this->comments->contains($comment)) {
$this->comments->add($comment);
}
}
public function removeComment(Comment $comment): void
{
$this->comments->removeElement($comment);
}
public function addTag(Tag ...$tags): void
{
foreach ($tags as $tag) {
if (!$this->tags->contains($tag)) {
$this->tags->add($tag);
}
}
}
public function removeTag(Tag $tag): void
{
$this->tags->removeElement($tag);
}
}
选项
allowDelete
默认情况下,您可以删除集合中包含的任何项目。如果您不想允许这样做,请使用此选项
1
yield CollectionField::new('...')->allowDelete(false);
renderExpanded
默认情况下,集合中的项目由显示其 __toString()
值的单行表示。用户需要单击每个项目以显示其嵌入式表单。如果您希望在页面加载时渲染所有展开的项目,请使用此选项
1
yield CollectionField::new('...')->renderExpanded();
setEntryIsComplex
如果每个集合项的嵌入式表单包含多个字段,请设置此选项
1
yield CollectionField::new('...')->setEntryIsComplex();
EasyAdmin 将尽力正确显示这些字段

setEntryType
集合的条目可以使用 Symfony 表单或 EasyAdmin CRUD 表单进行渲染。setEntryType()
方法定义了用于渲染每个集合条目表单的 Symfony 表单类型
1
yield CollectionField::new('...')->setEntryType(SomeType::class);
setEntryToStringMethod
默认情况下,集合中的项目由显示其 __toString()
值的单行表示。使用此选项定义如何获取每个集合条目的字符串表示形式
1 2 3 4 5 6 7 8 9
// this calls the 'getFullName()' method in the entity
yield CollectionField::new('...')->setEntryToStringMethod('getFullName');
// you can also pass a callable to generate the string
yield CollectionField::new('...')->setEntryToStringMethod(fn (): string => '...');
// your callable receives the entity and the translator service as arguments
yield CollectionField::new('...')->setEntryToStringMethod(
fn (Category $value, TranslatorInterface $translator): string => $translator->trans($value->getDescription())
);
showEntryLabel
默认情况下,EasyAdmin 隐藏每个集合项的表单标签(因为它是一个自增整数,在大多数情况下看起来不太好)。如果您希望显示该标签,请使用此选项
1
yield CollectionField::new('...')->showEntryLabel();
useEntryCrudForm
集合的条目可以使用 Symfony 表单或 EasyAdmin CRUD 表单进行渲染。useEntryCrudForm()
方法定义了用于渲染每个集合条目表单的 EasyAdmin CRUD 表单
1
yield CollectionField::new('...')->useEntryCrudForm();
默认情况下,EasyAdmin 会自动查找与属性关联的 CRUD 控制器。如果您需要更好地控制要使用的 CRUD 控制器,请将控制器的完全限定类名作为第一个参数传递
1 2 3 4 5 6 7
yield CollectionField::new('...')->useEntryCrudForm(CategoryCrudController::class);
// the other optional arguments are the CRUD page names to pass to the configureFields()
// method when creating and editing entries respectively
yield CollectionField::new('...')->useEntryCrudForm(
CategoryCrudController::class, 'new_category_on_article_page', 'edit_category_on_article_page'
);
注意
useEntryCrudForm()
方法需要 Symfony 6.1 或更高版本。
JavaScript 事件
当向集合字段添加项目时,将调度类型为 'ea.collection.item-added'
的 CustomEvent。 同样,当删除项目时,将调度类型为 'ea.collection.item-removed'
的 Event。
'ea.collection.item-added'
事件包含有关 detail 属性 中添加的项目的信息
1 2 3 4 5 6 7 8 9
document.addEventListener('ea.collection.item-added', (event) => {
const {newElement} = event.detail
console.debug(newElement, 'added to collection')
});
document.addEventListener('ea.collection.item-removed', (event) => {
// Do something with the event
console.debug('item removed from collection')
});