使用两个实体创建单个表单 [英] Using two entities to create a single form

查看:27
本文介绍了使用两个实体创建单个表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我问了一个类似的问题,但我认为它引起了混乱,所以我决定在这篇文章中用刷过的版本提问.

I asked a similar question to this but I think it caused confusion so I decided to ask in this post with brushed up version.

我想要的是在一个网络表单中打印来自两个不同实体的所有字段,BOTH TYPE.就是这样.

What I want is to print all fields from two different entities in a single web form, BOTH TYPE. That's it.

注意:我尝试在表单类型 (BOTH TYPE) 中使用 entitycollection 关键字,但 twig 没有回显任何内容.不断获得;对象的方法brand"或car"在树枝行中不存在....

Note: I tried using entity and collection keywords in the form type (BOTH TYPE) but twig doesn't echo anything. Keep getting; Method "brand" OR "car" for object does not exist in twig line whatever....

关系:1 个 Brand 有 N 个 Cars.一对多

Relationship: 1 Brand has N Cars. one-to-many

我阅读了如何嵌入表单集合"、实体字段类型"和集合字段类型",但无论我做什么,都不起作用.

I read the 'How to Embed a Collection of Forms', 'entity Field Type' and 'collection Field Type' but whatever I did, didn't work.

品牌实体

namespace Car\BrandBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

class BrandEntity
{
    protected $id;
    protected $name;
    protected $origin;

    /**
     * @ORM\OneToMany(targetEntity = "CarEntity", mappedBy = "brand")
     * @var object $car
     */
    protected $car;

    /**
     * Constructor.
     */
    public function __construct()
    {
        $this->car = new ArrayCollection();
    }
}

汽车实体

namespace Car\BrandBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

class CarEntity
{
    protected $id;
    protected $model;
    protected $price;

    /**
     * @ORM\ManyToOne(targetEntity="BrandEntity", inversedBy="car")
     * @ORM\JoinColumn(name="brand_id", referencedColumnName="id")
     * @var object $brand
     */
    protected $brand;
}

品牌类型

namespace Car\BrandBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class BrandType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->setAction($options['action'])
            ->setMethod('POST')
            ->add('name', 'text', array('label' => 'Name'))
            ->add('origin', 'text', array('label' => 'Origin'))
            ->add('button', 'submit', array('label' => 'Add'))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Car\BrandBundle\Entity\BrandEntity')
        );
    }

    public function getName()
    {
        return 'brand';
    }
} 

汽车类型

namespace Car\BrandBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class CarType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->setAction($options['action'])
            ->setMethod('POST')
            ->add('model', 'text', array('label' => 'Model'))
            ->add('price', 'text', array('label' => 'Price'))
            ->add('button', 'submit', array('label' => 'Add'))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Car\BrandBundle\Entity\CarEntity')
        );
    }

    public function getName()
    {
        return 'car';
    }
}

---------------------------------------------------------------------

-------- 本节是我试图让它工作的部分 ------

---------------------------------------------------------------------

两种类型

namespace Car\BrandBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Test\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class BothType extends AbstractType
{
    public function builder(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->setAction($options['action'])
            ->setMethod('POST')
            ->add('brand', 'collection', array('type' => new BrandType()))
            ->add('car', 'collection', array('type' => new CarType()))
            ->add('button', 'submit', array('label' => 'Add'))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Car\BrandBundle\Entity\BrandEntity',
            'cascade_validation' => true
        ));
    }

    public function getName()
    {
        return 'both';
    }
} 

控制器

namespace Car\BrandBundle\Controller;

use Car\BrandBundle\Form\Type\BothType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class BothController extends Controller
{
    public function indexAction()
    {
        $form = $this->createForm(new BothType(), null,
            array('action' => $this->generateUrl('bothCreate')));;

        return $this->render('CarBrandBundle:Default:both.html.twig',
                array('page' => 'Both', 'form' => $form->createView()));
    }
}

树枝

{% block body %}
    {{ form_label(form.brand.name) }}
    {{ form_widget(form.brand.name) }}
    {{ form_label(form.brand.origin) }}
    {{ form_widget(form.brand.origin) }}

    {{ form_label(form.car.model) }}
    {{ form_widget(form.car.model) }}
    {{ form_label(form.car.price) }}
    {{ form_widget(form.car.price) }}
{% endblock %}

推荐答案

使用数组来组合控制器中的两个对象.

Use an array to composite the two objects in your controller.

$formData = array(
    'brand' = new Brand(),
    'car' => new Car(),
);
$builder = $this->createFormBuilder($formData);
$builder->add('brand',new BrandFormType());
$builder->add('car', new CarFormType());

$form = $builder->getForm();

==============================================================
If you really want to make a BothType then just get rid of that collection type.

class BothType extends AbstractType
{
    public function builder(FormBuilderInterface $builder, array $options)
    {
    $builder
        ->setAction($options['action'])
        ->setMethod('POST')
        ->add('brand', new BrandType())
        ->add('car', new CarType())
        ->add('button', 'submit', array('label' => 'Add'))
    ;
    }

    // Controller
    $form = $this->createForm(new BothType(), $formData

当您有多个相同实体类型的实例时使用集合.

collection is used when you have multiple instances of the same entity type.

顺便说一下,为每个复合表单创建类会很快导致表单类型的爆炸式增长.因此,除非您计划在多个控制器之间重用您的 BothFormType,否则我建议您直接在控制器内部构建它.

By the way, creating classes for each composite form can quickly cause an explosion of form types. So unless you plan on reusing your BothFormType among multiple controllers then I'd suggest just building it right inside of the controller.

这篇关于使用两个实体创建单个表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆