Symfony2 dynamic forms mongodb

不想你离开。 提交于 2019-12-08 06:20:47

问题


Following the example as documented in the following http://symfony.com/doc/current/cookbook/form/dynamic_form_generation.html

I need to populate subcategory field according to the category selection. I don't understand why this error at /article/create:

FatalErrorException: Error: Call to a member function getSubCategories() on a non-object

the Form :

namespace Cc\HitoBundle\Form\Type;

…

class ArticleType extends AbstractType
{
    private $registrationArticleListener;

    public function __construct(RegistrationArticleListener $registrationArticleListener)
    {
        $this->registrationArticleListener = $registrationArticleListener;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            …

            ->add('category', 'document', array(
                'label' => 'Category',
                'class' => 'Cc\HitoBundle\Document\Category',
                'property' => 'name',
            ));


        $builder->addEventSubscriber($this->registrationArticleListener);
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Cc\HitoBundle\Document\Article'
        ));
    }

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

I don't understand what is the AddNameFieldSubscriber() function in the cookbook

The Listener:

namespace Cc\HitoBundle\Form\EventListener;

…

class RegistrationArticleListener implements EventSubscriberInterface
{
    /**
     * @var FormFactoryInterface
     */
    private $factory;

    /**
     * @var DocumentManager
     */
    private $dm;

    /**
     * @param factory FormFactoryInterface
     */
    public function __construct(FormFactoryInterface $factory, $mongo)
    {
        $this->factory = $factory;
        $this->dm = $mongo->getManager();
    }

    public static function getSubscribedEvents()
    {
        return array(
            FormEvents::PRE_BIND => 'preBind',
            FormEvents::PRE_SET_DATA => 'preSetData',
        );
    }

    /**
     * @param event FormEvent
     */
    public function preSetData(FormEvent $event)
    {
        $agent = $event->getData();

        if (null === $article) {
            return;
        }

        $form = $event->getForm();
        $subCategories = $article->getCategory()->getSubCategories();

        $this->customizeForm($form, $subCategories);
    }

    public function preBind(FormEvent $event)
    {
        $data = $event->getData();
        $id = $data['event'];
        $agent = $this->dm
            ->getRepository('CcHitoBundle:Article')
            ->find($id);

        if ($article === null) {
            $msg = 'The event %s could not be found for you registration';
            throw new \Exception(sprintf($msg, $id));
        }
        $form = $event->getForm();
        $subCategories = $article->getCategory()->getSubCategories();

        $this->customizeForm($form, $subCategories);
    }

    protected function customizeForm($form, $subCategories)
    {

    }
}

And I don't understand what I have to put in customizeForm function. Please help me !! =)


回答1:


You are getting the non-object error because you are not actually creating the $article variable in your preBind or preSetData functions. It looks like you are mixing up $agent and $article

public function preSetData(FormEvent $event)
{
    //here you have $agent
    $agent = $event->getData();
    //here you have $article
    if (null === $article) {
        return;
    }

    $form = $event->getForm();
    //here you have $article
    $subCategories = $article->getCategory()->getSubCategories();

    $this->customizeForm($form, $subCategories);
}

Change to:

public function preSetData(FormEvent $event)
{
    $article = $event->getData();
    // We can only set subcategories if a category is set
    if (null === $article->getCategory()) {
        return;
    }

    $form = $event->getForm();
    //...

In customise form function you want to add the fields you need like subCategories:

//taken from the article OP referenced
protected function customizeForm($form, $subCatQueryBuilder)
{
    $formOptions = array(
        'class' => 'You\YourBundle\Entity\SubCategory',
        'multiple' => true,
        'expanded' => false,
        'property' => 'THE_FIELD_YOU_WANT_TO_SHOW',
         // I would create a query builder that selects the correct sub cats rather than pass through a collection of objects
        'query_builder' => $subCatQueryBuilder,
    );
    // create the field, this is similar the $builder->add()
    // field name, field type, data, options
    $form->add($this->factory->createNamed('subCategories', 'entity', null, $formOptions));
}

For the query builder:

/**
 * @param event FormEvent
 */
public function preSetData(FormEvent $event)
{
    $agent = $event->getData();

    if (null === $article->getCategory()) {
        return;
    }

    $form = $event->getForm();

   //Something like
   $category = $article->getCategory();
   $subCatQueryBuilder =  $this->dm
      ->getRepository("YourCatBundle:Subcategory")
      ->createQueryBuilder("sc")
      ->join("sc.category", "c")
      ->where("c.id = :category")
      ->setParameter("category", $category->getId());
   $this->customizeForm($form, $subCatQueryBuilder);
}


来源:https://stackoverflow.com/questions/15968415/symfony2-dynamic-forms-mongodb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!