以 Symfony4 形式将实体对象值传递给嵌套的 CollectionTypes
Passing Entity object value in to nested CollectionTypes in a Symfony4 form
概述:在 Products
VariantSets
中 Foreach VariantGroup
我需要创建一个包含 VariantGroups
Variants
在 Symfony 形式中
详情:
我有一个 Product
实体,它作为 ManyToMany
关系关联到多个 VariantSet
对象。 VariantSet
对象包含多个 VariantGroup
对象,每个对象都需要生成一个下拉列表以显示其 Variant
个选项。
对于嵌套 CollectionTypes
,我只需要使与父 CollectionType
相关的选项可访问。
因此,唯一可用的 Variants
应该与 VariantGroups
相关,而这些 VariantGroups
仅与可用的 VariantSets
相关,而这些 VariantSets
与最初解析的 Product
相关联.
有一些信息指出使用查询生成器仅获取相关项目,但我想知道这是否是最佳做法。另外 - 我如何传递以前的表格(因此在 VariantGroup
的嵌套 CollectionType
中获得顶级 Product
,因为 VariantSets
位于这两者之间。
这甚至有可能在 Symfony 表单中使用最佳实践来实现吗?
所需输出示例 here
是的。答案是嵌套的 CollectionType
表单和最终表单中的自定义查询构建器(出于某种原因,它调用了数据库中的所有 Variant
对象,而不是使用与已解析的 VariantGroup
对象:
主要产品形态
class ComplexProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Render the variant sets based on the parsed product
$builder
->add('variantSets', CollectionType::class, [
'entry_type' => VariantSetComplexProductType::class,
'label'=> false,
'by_reference' => true,
] );
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
"data_class" => Product::class,
));
}
}
渲染产品变体集: (以获得与主要产品 VarianSet
对象关联的正确 VariantGroups
)
class VariantSetComplexProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Render the groups based on the Variant sets
$builder
->add( 'label' )
->add( 'variantGroups', CollectionType::class, [
'entry_type' => VariantGroupComplexProductType::class,
'label'=> false,
'by_reference' => true
] )
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults( [
'data_class' => VariantSet::class,
] )
;
}
}
在下拉列表中渲染变量集 VariantGroups
及其 Variants
:
Variant
对象的下拉需要使用 query_builder
选项在 FromEvent
中完成,否则我会遇到所有 Variant
对象的问题在数据库中被调用。
需要进行检查以确保根据已解析的 VariantGroup
.
只调用了正确的 Variant
对象
class VariantGroupComplexProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Render the drop downs based on the Parsed variant group
$builder
->add( 'label' )
// Rendering of the drop down must be done after the previous form data is available
->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'preSetData']);
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults( [
'data_class' => VariantGroup::class,
] );
}
public function preSetData(FormEvent $event)
{
$form = $event->getForm();
/** @var VariantGroup $child */
$child = $event->getData();
$form
->add('variants', EntityType::class, array(
'class' => Variant::class,
'by_reference' => true,
'query_builder' => function (EntityRepository $er) use ( $child ) {
return $er->createQueryBuilder('u')
->where('u.variant_group = :variant_group')
->setParameter('variant_group', $child )
->orderBy('u.label', 'DESC');
},
'choice_label' => 'label',
));
}
}
概述:在 Products
VariantSets
中 Foreach VariantGroup
我需要创建一个包含 VariantGroups
Variants
在 Symfony 形式中
详情:
我有一个 Product
实体,它作为 ManyToMany
关系关联到多个 VariantSet
对象。 VariantSet
对象包含多个 VariantGroup
对象,每个对象都需要生成一个下拉列表以显示其 Variant
个选项。
对于嵌套 CollectionTypes
,我只需要使与父 CollectionType
相关的选项可访问。
因此,唯一可用的 Variants
应该与 VariantGroups
相关,而这些 VariantGroups
仅与可用的 VariantSets
相关,而这些 VariantSets
与最初解析的 Product
相关联.
有一些信息指出使用查询生成器仅获取相关项目,但我想知道这是否是最佳做法。另外 - 我如何传递以前的表格(因此在 VariantGroup
的嵌套 CollectionType
中获得顶级 Product
,因为 VariantSets
位于这两者之间。
这甚至有可能在 Symfony 表单中使用最佳实践来实现吗?
所需输出示例 here
是的。答案是嵌套的 CollectionType
表单和最终表单中的自定义查询构建器(出于某种原因,它调用了数据库中的所有 Variant
对象,而不是使用与已解析的 VariantGroup
对象:
主要产品形态
class ComplexProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Render the variant sets based on the parsed product
$builder
->add('variantSets', CollectionType::class, [
'entry_type' => VariantSetComplexProductType::class,
'label'=> false,
'by_reference' => true,
] );
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
"data_class" => Product::class,
));
}
}
渲染产品变体集: (以获得与主要产品 VarianSet
对象关联的正确 VariantGroups
)
class VariantSetComplexProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Render the groups based on the Variant sets
$builder
->add( 'label' )
->add( 'variantGroups', CollectionType::class, [
'entry_type' => VariantGroupComplexProductType::class,
'label'=> false,
'by_reference' => true
] )
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults( [
'data_class' => VariantSet::class,
] )
;
}
}
在下拉列表中渲染变量集 VariantGroups
及其 Variants
:
Variant
对象的下拉需要使用 query_builder
选项在 FromEvent
中完成,否则我会遇到所有 Variant
对象的问题在数据库中被调用。
需要进行检查以确保根据已解析的 VariantGroup
.
Variant
对象
class VariantGroupComplexProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Render the drop downs based on the Parsed variant group
$builder
->add( 'label' )
// Rendering of the drop down must be done after the previous form data is available
->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'preSetData']);
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults( [
'data_class' => VariantGroup::class,
] );
}
public function preSetData(FormEvent $event)
{
$form = $event->getForm();
/** @var VariantGroup $child */
$child = $event->getData();
$form
->add('variants', EntityType::class, array(
'class' => Variant::class,
'by_reference' => true,
'query_builder' => function (EntityRepository $er) use ( $child ) {
return $er->createQueryBuilder('u')
->where('u.variant_group = :variant_group')
->setParameter('variant_group', $child )
->orderBy('u.label', 'DESC');
},
'choice_label' => 'label',
));
}
}