我问了一个类似的问题,但我认为这引起了混乱,所以我决定在这篇文章中提出刷新版本。
我想要的是在一个网络表单中打印两个不同实体的所有字段, BOTH TYPE 。就是这样。
注意:我尝试在表单类型中使用entity
和collection
个关键字( BOTH TYPE ),但twig不会回显任何内容。继续; Method "brand" OR "car" for object does not exist in twig line whatever....
关系:1 Brand
有N Cars
。一个对多
我阅读了“如何嵌入表单集合”,“实体字段类型”'和'收集字段类型'但不管我做了什么,都没有用。
品牌实体
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();
}
}
CAR ENTITY
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';
}
}
CAR TYPE
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';
}
}
-------------------------------------------- -------------------------
--------此部分是我试图让它发挥作用的部分------
-------------------------------------------- -------------------------
BOTH TYPE
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';
}
}
CONTROLLER
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()));
}
}
TWIG
{% 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 %}
答案 0 :(得分:1)
使用数组合成控制器中的两个对象。
$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
如果您有多个相同实体类型的实例,则使用集合。
顺便说一句,为每个复合表单创建类可能会很快导致表单类型的爆炸。因此,除非您计划在多个控制器之间重用您的BothFormType,否则我建议您只在控制器内部构建它。