【问题标题】:Symfony2 - Apply a DataTransformer to a collection in formsSymfony2 - 将 DataTransformer 应用于表单中的集合
【发布时间】:2013-05-22 16:41:16
【问题描述】:

我需要制作一个 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;
}
}

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

提前致谢。

【问题讨论】:

  • 你在 DataTransformer::transform 中做什么? if (null === $student->toArray()) { return $array; } 返回$数组; ??为什么不立即返回 new \Doctrine\Common\Collections\ArrayCollection(); ?
  • 一个电子邮件地址是否与多个学生有关?
  • 为什么不在学生类型中添加转换器?
  • 如果我理解正确......您想要一个输入/选择字段(带有 javaScript 建议),其中(按课程过滤)学生的电子邮件地址将被自动完成。看我的回答。

标签: symfony collections doctrine


【解决方案1】:

您要查找的不是 DataTransfomer,而是 entity field type

您可以通过嵌入具有实体字段类型 .... 的子表单来获得这种类型的输入,由 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)”之类的内容。

【讨论】:

  • 非常感谢,最后我决定实施 nifr 的解决方案。我正在寻找一个像 selected 一样的 jQuery 插件,我找到了 jquery-ui-multiselect。除此之外,如果我的解释不够清楚,我深表歉意,但在我的用例中,我想将学生添加到平台上所有学生的课程中,以便查询按课程过滤学生,这对我的情况不正确.否则,我想知道 DataTransformers 的用途是什么。据我了解,它们用于将数据从模型转换为规范化,或从规范化转换为形式并向后转换。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-14
  • 2012-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多