本文介绍了具有教义类表继承(STI)的Symfony表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个上一个问题中,我问如何处理大表格,结果是单表继承(STI)或CTI,继承映射.我选择了CTI.

In a previous question I ask how to handle large forms, outcome was Single Table Inheritance (STI) or CTI, Inheritance mapping. I've has chosen for CTI.

现在,我正在处理如何使用CTI创建表单.快速概览是什么类型或关系.

Now i'm dealing how to create the form with CTI. A quick overview what kind or relation there are.

每个inspection可以具有一个或多个surfaces.每个表面都包含许多子实体,例如:surface_leakagesurface_tensionsurface_slope.如您所见,surface具有带有子实体的CTI.有些字段重叠(将其放在父级中),有些则不重叠(将其放在子级中).但是最后,我需要一种形式,其中所有字段都按曲面分组,然后按子分组(Bootrap可能会崩溃).

Each inspection could have one or more surfaces. Each surface consists of many sub entities, like: surface_leakage, surface_tension or surface_slope. As you could see surface has the CTI with sub entities. Some fields overlap (put them in parent), some don't (put them in child). But in the end I need one form with all the fields grouped by surfaces then by child (maybe Bootrap collapse).

设置关系并不难,但是很难将其用于表单中,我不确定如何处理.参见下面的代码,其中包含两个方法

Setting up the relation was not that hard, but to use it into a form is difficult and I'm not sure how I could handle this. See below code with in code two approuches

<?php
class Inspection
{
    /**
     * @OneToMany(targetEntity="App\Entity\Surface", mappedBy="inspection")
     */
    protected $surfaces;
}

/**
 * @Entity
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="discr", type="string")
 * @DiscriminatorMap({"surface" = "Surface", "surface_leagage" = "SurfaceLeakage", ...})
 */
class Surface
{
    protected $inpection;
    protected $description;
}

class SurfaceLeakage extends Surface
{
    protected $leakageLevel;
}

// .. other child classes (SurfaceTension, SurfaceSlope, ...)

class InspectionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // ...

        $builder->add('surfaces', CollectionType::class, [
            'entry_type' => SurfaceType::class,
        ]);
    }
}

// Approach 1, where each child is added to the SurfaceType
// with this approach data should be mapped false
// This approach ensures that I only have to call SurfaceType once and all fields are loaded, but
// could not make this work with data from DB through CIT.
// Also this method does not allow me to add field description (from parent) to all childTypes
class SurfaceType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('leakage', SurfaceLeakageType::class, array('mapped' => false));
        $builder->add('tension', SurfaceTensionType::class, array('mapped' => false));
        //  ...
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Surface::class,
        ]);
    }
}

class SurfaceLeakageType extends AbstractType
{

}

// Approach 2, where each childFormType could extend SurfaceType, like below but how to call/create the
// form and handling the data.
// With this approuch i could parent fields to the child
class SurfaceLeakageType extends SurfaceType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('description', TextareaType::class); // field from parent or ...
        parent::buildForm($builder, $options);


        $builder->add('leakageLevel', IntegerType::class); // own field
        //  ...
    }
}

然后是 inherit_data

// Approach 3, inherit data, now each child should add this as a field like below,
// but how the only thing I'm doing on InspectionType build Surfaces as collection so
// i think inherit data also doesn't work
class SurfaceType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder->add('description', TextareaType::class);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'inherit_data' => true,
        ]);
    }
}

class SurfaceLeakageType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // inherit fields
        $builder->add('leakage', SurfaceType::class, [
            'data_class' => SurfaceLeakage::class,
        ]);

        $builder->add('leakageLevel', IntegerType::class); // own field
    }
}

希望有人可以帮助我

推荐答案

我认为您正在寻找多态形式.检查此捆绑包 https://github.com/infinite-networks/InfiniteFormBundle

I think you are looking for polymorphic forms. Check this bundle https://github.com/infinite-networks/InfiniteFormBundle

这篇关于具有教义类表继承(STI)的Symfony表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-13 04:13