Symfony hiddenType使用data_class代替变换器

时间:2016-02-25 23:32:13

标签: php symfony doctrine

所以我试着将我的一个实体的id存储在hiddenType中,然后我得到了:

表单的视图数据应该是标量,数组或\ ArrayAccess实例的类型,但是是AppBundle \ Entity \ Users类的实例。您可以通过设置" data_class"来避免此错误。选项" AppBundle \ Entity \ Users"或者添加一个视图转换器,将AppBundle \ Entity \ Users类的实例转换为标量,数组或\ ArrayAccess的实例。

data_class :"此选项用于设置表单使用的相应数据映射器,因此您可以将其用于需要对象的任何表单字段类型。&# 34;

请参阅:http://symfony.com/doc/2.7/reference/forms/types/form.html#data-class

所以我修复了我的表单:

$builder
    ->add('user', 'hidden', array(
        'data_class' => 'AppBundle\Entity\User',
    ));

当我尝试这个时,我得到一个例外,说明我的实体无法翻译成字符串

所以我在我的实体上实现了__tostring魔术方法来返回实体的id,然后twig能够将实体id放在隐藏字段值中

然后当我尝试提交表格时,我得到:

捕获致命错误:参数1传递给AppBundle \ Entity \ Students :: setUser()必须是AppBundle \ Entity \ Users的实例,给定字符串,在/ vendor / symfony / symfony / src / Symfony中调用第442行的/Component/PropertyAccess/PropertyAccessor.php并定义了

所以它无法将请求中的字符串值拉回到我的表单中使用的实体。

是的,我已经看到了使用变换器构建entityHiddenType的实现。

但是我问这是否可以使用symphony提供的data_class设置,因为我相信这是解决这个问题的预期方法?

我只想知道是否可以使用data_class而不是变换器来实现。以及哪种方法是最佳实践。

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题,我通过在我的data_class中将null设置为HiddenType来解决这个问题:

<?php namespace AppBundle\Forms\Signup;


use AppBundle\Entity\Course;
use AppBundle\Repository\CourseRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PreselectedCourseType extends AbstractType
{
    private $courseRepository;

    public function __construct(CourseRepository $courseRepository)
    {
        $this->courseRepository = $courseRepository;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $selectedCourse = $options['selected_course'];

        $builder
            ->add("course", HiddenType::class,['data' => $selectedCourse, 'data_class' => null]);


        $builder->get("course")->addModelTransformer(new CallbackTransformer(
            function (Course $course = null) {return $course? $course->getId():0;},
            function ($course = null) {return $this->courseRepository->getCourse($course);}
        ));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => CourseDTO::class,
            'label' => false,
            'selected_course' => 0
        ]);
        $resolver->setRequired("selected_course");
    }
}