Symfony2动态形成mongodb

时间:2013-04-12 10:00:32

标签: mongodb symfony doctrine-odm

按照以下http://symfony.com/doc/current/cookbook/form/dynamic_form_generation.html

中记录的示例进行操作

我需要根据类别选择填充子类别字段。 我不明白为什么这个错误在/ article / create:

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

表格:     

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

我不明白食谱中的 AddNameFieldSubscriber()功能是什么

听众:     

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)
    {

    }
}

我不明白我必须在customizeForm函数中添加什么。请帮我 !! =)

1 个答案:

答案 0 :(得分:1)

您收到非对象错误,因为您实际上并未在preBind或preSetData函数中创建$ article变量。看起来您正在混淆$agent$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);
}

更改为:

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();
    //...

在自定义表单功能中,您希望添加所需的字段,如子类别:

//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));
}

对于查询构建器:

/**
 * @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);
}