2017-02-08 14 views
1

У меня есть Entity продукт с ArrayCollection из FeatureTypes (ManytoMany) Класс продукта:Symfony FormType, получить выпадающий список ArrayCollection

/** 
* @var FeatureType 
* 
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\FeatureType", mappedBy="products") 
*/ 
private $featureTypes; 

public function __construct() 
{ 
    $this->variants = new ArrayCollection(); 
    $this->featureTypes = new ArrayCollection(); 
} 

Класс FeatureType:

/** 
* @var Product[]|ArrayCollection 
* 
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Product", inversedBy="featureTypes") 
* @ORM\JoinTable(name="products_featureTypes") 
*/ 
private $products; 

Теперь я хочу, чтобы создать формы, которые предоставляют мне раскрывающийся список всех доступных типов признаков. Я хочу выбрать один и отправить его.

Я попробовал, как это в моем addFeatureTypeToProductType:

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('featureTypes', EntityType::class, [ 
      'class' => FeatureType::class, 
      'choice_label' => 'name', 
     ]) 
     ->add('submit', SubmitType::class) 
     ->getForm(); 
} 

Выходом является Dropdown со всеми доступными FeatureTypes. Но когда я отправляю выбранный featureType, я получаю сообщение об ошибке: «Не удалось определить тип доступа для свойства« featureType ».

Тогда я попробовал этот путь:

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('featureTypes', CollectionType::class, [ 
      'entry_type' => FeatureType::class, 
      'allow_add' => true, 
     ]) 
     ->add('submit', SubmitType::class) 
     ->getForm(); 
} 

Но это не работает

Мой контроллер:

public function addFeatureTypeAction(Request $request, Product $product) 
{ 
    $form = $this->createForm(AddFeatureTypeToProductType::class, $product, [ 
     'action' => $this->generateUrl('admin_products_add_featureTypes', [ 
      'product' => $product->getId() 
     ]) 
    ]); 

    $form->handleRequest($request); 


    if($form->isSubmitted() && $form->isValid()) { 
     $featureType = $form->get('featureTypes'); 
     $product->addFeatureTypes($featureType); 
     $em = $this->getDoctrine()->getManager(); 
     $em->persist($product); 
     $em->flush(); 

     return $this->redirectToRoute('admin_products_list_all'); 
    } 

    return [ 
     'form' => $form->createView() 
    ]; 
} 

Извините за мой английский: S

EDIT: Вот мой сумматор/съемник и сеттер/приемник:

/** 
* @return FeatureType 
*/ 
public function getFeatureTypes() 
{ 
    return $this->featureTypes; 
} 

/** 
* @param FeatureType $featureTypes 
*/ 
public function setFeatureTypes($featureTypes) 
{ 
    $this->featureTypes = $featureTypes; 
} 


/** 
* Add new FeatureType 
* 
* @param FeatureType $featureType 
* 
* @return Product 
*/ 
public function addFeatureTypes($featureType) 
{ 
    if (!$this->featureTypes->contains($featureType)) { 
     $this->featureTypes->add($featureType); 
    } 

    return $this; 
} 

/** 
* @param FeatureType $featureType 
* 
* @return Product 
*/ 
public function removeFeatureTypes($featureType) 
{ 
    if ($this->featureTypes->contains($featureType)) { 
     $this->featureTypes->remove($featureType); 
    } 

    return $this; 
} 

РЕДАКТИРОВАТЬ 2: Я попробовал это снова с помощью первого способа моей формы. Но теперь я получаю новую ошибку. Я не знаю, почему мой объект «FeatureType» не знает метод contains. Он использует Symfony Arraycollection

Ошибка: Попытка вызвать неопределенный метод с именем «содержит» класса «AppBundle \ Entity \ FeatureType».

Отладка останавливается в addFeatureTypes ($ FeatureType)

Im один шаг теперь. Теперь я использую collectionType.

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('featureTypes', CollectionType::class, [ 
      'entry_type' => FeatureTypeType::class, 
      'allow_add' => true, 
     ]) 
     ->add('submit', SubmitType::class) 
     ->getForm(); 
} 

Моя внешняя форма показывает все признаки, которые у моего продукта уже есть. Но я не знаю, как добавить еще один ...

+0

Почему вы называете 'getForm()' внутри вашей формы 'buildForm()' met корыто? У вас есть методы getter и setter/adder для свойства '$ featureTypes' вашего объекта' Product'? – xabbuh

+0

Ну, я узнал это на этом пути (getForm()). И он работает во всех Формах. Да, у меня есть геттер/сеттер и сумматор/съемник, я добавил его к моему вопросу :) –

+0

Извините, забыли ссылку @xabbuh –

ответ

0

Аннотации моих свойств были неправильными. Класс продукта:

/** 
* @var FeatureType[]|ArrayCollection 
* 
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\FeatureType", inversedBy="products", cascade={"persist"}) 
* @ORM\JoinTable(name="products_featureTypes") 
*/ 
private $featureTypes; 

Класс FeatureType:

/** 
* @var Product[]|ArrayCollection 
* 
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Product", mappedBy="featureTypes", cascade={"persist"}) 
* 
*/ 
private $products; 

Моя форма:

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('featureTypeToAdd', EntityType::class, [ 
      'class'  => FeatureType::class, 
      'choice_label' => 'name', 
      'mapped'  => false, 
     ]) 
     ->add('submit', SubmitType::class) 
     ->getForm(); 
} 

И мой контроллер:

public function addFeatureTypeAction(Request $request, Product $product) 
{ 
    $form = $this->createForm(AddFeatureTypeToProductType::class, $product, [ 
     'action' => $this->generateUrl('admin_products_add_featureTypes', [ 
      'product' => $product->getId(), 
     ]), 
    ]); 

    $form->handleRequest($request); 

    if ($form->isSubmitted() && $form->isValid()) { 
     $featureType = $form->get('featureTypeToAdd')->getData(); 
     $em = $this->getDoctrine()->getManager(); 
     $product->addFeatureTypes($featureType); 
     $em->persist($product); 
     $em->flush(); 

     return $this->redirectToRoute('admin_products_list_all'); 
    } 

    return [ 
     'form' => $form->createView(), 
    ]; 
}