2014-06-19 63 views
1

我問了一個類似的問題,但我認爲這造成了困惑,所以我決定在這個帖子中詢問刷過的版本。使用兩個實體來創建一個表單

我想要的是打印來自兩個不同實體的所有領域在一個單一的網絡形式,兩種類型。而已。

注:我試圖在表單類型使用entitycollection關鍵字(類型都是),但樹枝不會回任何東西。繼續;

關係:1 Brand有N Cars。一個一對多

enter image description here

我讀了「如何嵌入表單的集合」,「實體字段類型」和「集合字段類型」但無論我做到了,沒有工作。

品牌實體

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實體

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'; 
    } 
} 

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

--------本節爲我試圖讓它工作------

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

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,那麼我建議在控制器內部直接構建它。

+0

是的,它可以工作,但我沒有在我的控制器中使用表單生成器,所以如何在上面的代碼中實現它? – BentCoder

+0

已更新的答案。 – Cerad

+0

爲此,創建表單作爲別名與getName()相同的服務,然後您可以像' - > add('brand','the.alias.for.brand')那樣使用它們。 – qooplmao

相關問題