Symfony hiddenType 使用 data_class for 实体而不是转换器


Symfony hiddenType using data_class for entity instead of transformer

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

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

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

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

所以我修复了我的表单:

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

当我尝试这样做时,我得到一个异常,指出我的实体无法转换为字符串

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

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

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

因此,它无法将请求中的字符串值拉回实体以在我的表单中使用。

是的,我已经看到了使用转换器构建实体HiddenType的实现。

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

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

我遇到了同样的问题,我通过将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");
    }
}