【问题标题】:multiple nested collection fields & sonata_type_collection多个嵌套集合字段和奏鸣曲类型集合
【发布时间】:2014-12-31 09:37:56
【问题描述】:

我对奏鸣曲管理包还很陌生,我可以使用一些帮助。

问题:

我有一个 Quiz 实体、一个 Question 实体、一个 Answer 实体。

测验和问题之间的关系:一对多。

测验实体

/**
* @ORM\OneToMany(targetEntity="Question", mappedBy="quiz", cascade={"persist", "remove"})
*/
protected $questions;

问题实体

/**
* @ORM\ManyToOne(targetEntity="Quiz", inversedBy="questions", cascade={"persist"})
* @ORM\JoinColumn(name="quiz_id", referencedColumnName="id", nullable = false)
*/
protected $quiz;

关系问答:一对多。

问题实体

/**
* @ORM\OneToMany(targetEntity="Answer", mappedBy="question", cascade={"persist", "remove"})
*/
protected $answers;

回答实体

/**
* @ORM\ManyToOne(targetEntity="Question", inversedBy="answers")
* @ORM\JoinColumn(name="question_id", referencedColumnName="id")
*/
protected $question;

我需要一个表格,我可以在其中向课程添加多个问题,每个问题可以有一个或多个答案,这些答案也应该有一个真假标志。

所以基本上我需要这样的东西: mockup

到目前为止,我设法只添加了来自管理员的多个问题。实际上,在几个版本之前(奏鸣曲管理和学说),我的问题和答案都在工作。但是现在我只能添加多个问题,而无法添加任何答案。

这是我的 QuestionType 类:

<?php

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class QuestionType extends AbstractType {

    public function buildForm( FormBuilderInterface $builder, array $options )
    {
        $builder
            ->add('text', 'text', array( 'required' => false, 'label' => 'question' ) )
            ->add('answers', 'collection', array(
                    'type'               => new AnswerType(),
                    'allow_add'          => true,
                    'allow_delete'       => true,
                    'by_reference'       => false,
                    'delete_empty'       => true,
                    'cascade_validation' => false,
                    'label'              => 'Answers',
                    'options'            => array( 'label' => false ),
                    'label_attr'         => array( 'class' => 'answers' ),
            ));
    }


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

    public function setDefaultOptions( OptionsResolverInterface $resolver )
    {
        $resolver->setDefaults( array(
            'data_class' => MyBundle\CoreBundle\Entity\Question',
        ));
    }

}

这是我的 AnswerType 类:

<?php

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class AnswerType extends AbstractType {

    public function buildForm( FormBuilderInterface $builder, array $options )
    {
        $builder
            ->add('text', 'text', array( 'required' => true, 'label' => 'answer' ) )
            ->add('correct', 'checkbox', array( 'required' => false ) );
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'answers';
    }

    public function setDefaultOptions( OptionsResolverInterface $resolver )
    {
        $resolver->setDefaults( array(
            'data_class' => 'MyBundle\CoreBundle\Entity\Answer',
        ));
    }

}

这是我的 QuizAdmin 课程:

<?php 

use MyBundle\CoreBundle\Form\QuestionType;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Route\RouteCollection;

class QuizAdmin extends Admin
{

    // Fields to be shown on create/edit forms
    protected function configureFormFields( FormMapper $formMapper )
    {
        $formMapper
            ->add('title', 'text', array( 'label' => 'Quiz Title' ) )
            ->add('description', 'textarea', array( 'label' => 'Quiz Description' ) )
            ->add('private', 'checkbox', array('required' => false ) )
            ->add('questions', 'collection', array(
                    'type'               => new QuestionType(),
                    'allow_add'          => true,
                    'allow_delete'       => true,
                    'cascade_validation' => false,
                    'by_reference'       => false,
                    'delete_empty'       => true,
                    'options'            => array( 'label' => false ),
            ));
    }

    // Fields to be shown on filter forms
    protected function configureDatagridFilters( DatagridMapper $datagridMapper )
    {
        $datagridMapper
            ->add( 'title' );
    }

    // Fields to be shown on lists
    protected function configureListFields( ListMapper $listMapper )
    {
        $listMapper
            ->addIdentifier( 'title' );
    }
}

我也尝试过使用 sonata_type_collection 但它不起作用,它返回此错误: “当前字段“问题”未链接到管理员。请为目标实体创建一个“ 我已经查看了这个并尝试了stackoverflow上建议的所有内容,但我无法让它工作。 我非常感谢任何关于这个问题的建议。

这是测验的管理页面当前的样子,其中包含问题和答案:

sample

正如我在运行 composer.phar update 之前的几个版本之前提到的那样,我可以添加问题和答案(我不记得版本,但后来我遇到了一些独特字段的其他问题,我很高兴得到了修复,但现在我遇到了这个问题)。

如果您有任何建议,我很乐意遵循。

谢谢!

【问题讨论】:

    标签: symfony collections admin sonata


    【解决方案1】:

    嗨,我的朋友们,这是我的第一个答案,我希望它有用。
    我怎样才能为几个 lewel 做嵌套收集:
    1) 创建 AnswerType
    2) 不要创建 QuestionType
    3) 在 QuestionAdmin 中使用集合 AnswerType
    4) 在 QuizAdmin 中使用 sonata_type_collection 作为问题实体

    【讨论】:

      【解决方案2】:

      我的项目中还有一个测验系统,我的实体和你一样。

      您必须为每个实体创建控制器和管理员:

      • 测验:QuizzAdmin / QuizzController
      • 问题:QuestionAdmin / QuestionController
      • 答案:AnswerAdmin / AnswerController

      这将解决您的错误:当前字段“问题”未链接到管理员。请为目标实体创建一个。

      我使用 sonata_type_collection 作为字段类型,您必须使用此要点:https://github.com/sonata-project/SonataAdminBundle/pull/1971/files,否则您将无法添加答案。

      您只需要更改您的字段答案以匹配我的课程中的答案。

      测验管理员:

      class QuizzAdmin extends Admin
      {
          protected function configureListFields(ListMapper $listMapper)
          {
               $formMapper->add('questions', 'sonata_type_collection',
                   array(
                       'by_reference' => false
                   ),
                   array(
                       'edit' => 'inline',
                       'inline' => 'table'
                  )
              );
          }
      }
      

      问题管理员:

      class QuestionAdmin
      {
          protected function configureFormFields(FormMapper $formMapper)
          {
              $formMapper->add('answers', 'sonata_type_collection',
                  array(
                      'by_reference' => false
                   ),
                   array(
                       'edit' => 'inline',
                       'inline' => 'table'
                  )
              );
          }
      }
      

      您还应该考虑在您的管理员类中添加以下代码,以便在您在管理员中添加测验时触发您对问题和答案的断言验证:

      class QuizzAdmin extends Admin 
      {
          protected $formOptions = array(
              'cascade_validation' => true
          );
      }
      

      【讨论】:

      • 嗨,我正在使用嵌套的“sonata_type_collection”做与此非常相似的事情,但我遇到了一个问题,我正在使用答案中提到的要点。当我只有一个集合时,一切都显示得很好,但是当我嵌套它们时,第一个集合的孩子就会消失。你知道为什么吗(你的quizadmin类也有错误,你使用了configureListFields方法,它应该是configureFormFields,并且编辑队列已满)
      猜你喜欢
      • 2019-08-11
      • 2013-08-27
      • 1970-01-01
      • 2021-01-09
      • 1970-01-01
      • 2015-01-03
      • 1970-01-01
      • 1970-01-01
      • 2021-03-11
      相关资源
      最近更新 更多