1

我需要制作一个 Symfony2 表单并将一个数据转换器添加到一个集合中。我有一个 StudentType 表单,它有一个隐藏字段,其中包含一个唯一的学生邮件。案例使用是具有多个学生(oneToMany 关系)的课程,我有一个课程表单,其中包含通过邮件或姓名搜索用户的建议输入。然后,通过 javascript,我动态添加表单集合,并使用在建议输入中选择的学生邮件设置隐藏值邮件。直到这里一切都运行正常,但我需要应用一个数据转换器,将这些隐藏字段与学生邮件以及与这些邮件对应的学生对象数组进行转换。因为在控制器中,它抛出了一个异常,因为 Course Entity 的 addStudent() 方法需要一个 Student 对象。

class StudentType extends AbstractType
{
    private $container;

    public function __construct(Container $container)
    {
       $this->container = $container;
    }

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

        $builder->add(
            $builder->create('mail','hidden', array(
                'required' => false,
                'label' => '',
                'attr' => array(
                    'class' => 'student_mail')
                )
        ));

    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'validation_groups' => array('backoffice_register')
        ));
    }

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

}

我已经将该类定义为注入服务容器的服务:

backoffice.form.courseforms.student:
    class: ...\StudentType
    arguments:
        - '@service_container'
    tags:
        - { name: form.type, alias: CourseStudents }

因此,在 CourseType 表单中,我添加了一组 StudentType 表单并应用了 DataTransformer:

$transformer = new StudentMailTransformer($this->container->get('doctrine')->getManager());
....
$builder->add($builder->create('students', 'suggest', array(
            'type' => 'CourseStudents',
            'attr' => array(
                'title' => 'Search students',
                'placeholder' => 'Search students by mail',
                'class' => 'student_suggest')
            ))->addModelTransformer($transformer)
        )

最后,数据转换器:

class StudentMailTransformer implements DataTransformerInterface
{
/**
 * @var ObjectManager
 */
private $om;

/**
 * @param ObjectManager $om
 */
public function __construct(ObjectManager $om)
{
    $this->om = $om;
}

public function transform($student)
{
    $array = new \Doctrine\Common\Collections\ArrayCollection();


    if (null === $student->toArray()) {
        return $array;
    }

    return $array;
}

public function reverseTransform($students)
{
    $students = new \Doctrine\Common\Collections\ArrayCollection();

    $array = $students->toArray();

    foreach ($array as $value) {

        $student = $this->om->getRepository('AcmeUserBundle:Student')->findOneBy(array('mail' => $value['mail']));

        if (null === $student) {
            throw new TransformationFailedException(sprintf(
                'Student with mail "%s" does not exist!',
                $mail
            ));
        }

        $students->add($student);
    }

    return $students;
}
}

为此,我想获得一个数据转换器,它将 StudentType 的集合(带有一个名为 mail 的字段)转换为与这些邮件对应的 Student 对象的集合。

提前致谢。

4

1 回答 1

1

您正在寻找的不是 DataTransfomer,而是实体字段类型

您可以通过嵌入具有实体字段类型的子表单来获得这种类型的输入....过滤query_builder以仅匹配课程中的那些学生。

您可以使用多个选项将其呈现为 html 中的选择或复选框,并使用 JavaScript 轻松将其转换为自动建议输入。

$builder->add('users', 'entity', array(
    'class'         => 'AcmeHelloBundle:Student',
    'multiple'      => true
    'property'      => 'email',
    'query_builder' => function(EntityRepository $er) {

        return $er->createQueryBuilder('u')
            ->orderBy('u.username', 'ASC');
            ->where('u.course = :course')
            ->setParameter('course', $course)
    },
));

现在使用jQuery Chosen之类的东西来自动完成建议。

使用另一个 queryBuilder 将标签填充为“Firstname Lastname (mail@host.com)”之类的内容。

于 2013-05-23T02:12:59.817 回答