呈现包含文件类型的 Symfony 4 编辑表单时出错
error when rendering Symfony 4 edit form that includes a File type
我正在按照本文档 https://symfony.com/doc/current/controller/upload_file.html 中列出的步骤来允许上传文件。它非常适合添加新项目,但是当我尝试编辑我的实体时,出现以下错误:
表单的视图数据应该是 class Symfony\Component\HttpFoundation\File\File 的一个实例,但却是一个 (n) 字符串。您可以通过将 "data_class" 选项设置为 null 或添加一个将 (n) 字符串转换为 Symfony\Component\HttpFoundation\File\File.
实例的视图转换器来避免此错误
我已经尝试使用该文章中建议的代码,在我的更新方法中将文件夹路径作为文件类型附加到实体,如下所示:
public function editAction(Request $request, Advertiser $advertiser)
{
$advertiser->setLogo(
new File($this->getParameter('logo_directory') .'/' . $advertiser->getLogo())
);
$editForm = $this->createForm(AdvertiserType::class, $advertiser);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('advertiser_list');
}
return $this->render('advertiser/index.html.twig', [
'form' => $editForm->createView()
]);
}
logo_directory 参数已正确定义(并且可以很好地创建新实体)。
如果您有任何想法,请告诉我我做错了什么。
感谢您的帮助。
更新:在这篇文章 中,有一个提议的解决方案是在表单构建器代码中包含以下内容:
->add('file', FileType::class, array('data_class' => null))
所以我现在正在这样做,编辑表单将显示 - 但它不会预先填充之前的选择。
->add('logo', FileType::class, array('data_class' => null), ['label' => 'Logo (JPG or PNG file)'])
有没有想过如何更改它以允许表单显示之前预填充的选择?
设置空 data_class
将删除警告,但它不会起作用,此时您不需要它。
这是因为一旦您的文件被持久化,保留在数据库中的只是一个路径,而不是文件本身(它在磁盘上);
如果要再次编辑此实体,路径(字符串)必须再次转换为文件实体;这就是错误消息所说的。
.. 这就是你写的时候所做的:
$advertiser->setLogo(
new File($this->getParameter('logo_directory') .'/' . $advertiser->getLogo())
);
现在,剩下的问题是您要预填充文件字段。事实上,这是不可能的,因为文件字段指向你自己电脑中的一个位置,而不是你服务器上的文件(而且你不能像那样自动从别人的电脑上传东西,那会很危险).
您想要做的可能是指示文件已存储,获取其路径并可能将其显示给您的用户。
所以在你的 Twig 模板中,类似的东西(更改为你的真实徽标目录):
{% if form.logo.vars.data %}
<img src="{{ asset('/uploads/logos_directory/' ~ form.logo.vars.data.filename) }}"/>
{% endif %}
希望清楚。
我正在按照本文档 https://symfony.com/doc/current/controller/upload_file.html 中列出的步骤来允许上传文件。它非常适合添加新项目,但是当我尝试编辑我的实体时,出现以下错误:
表单的视图数据应该是 class Symfony\Component\HttpFoundation\File\File 的一个实例,但却是一个 (n) 字符串。您可以通过将 "data_class" 选项设置为 null 或添加一个将 (n) 字符串转换为 Symfony\Component\HttpFoundation\File\File.
实例的视图转换器来避免此错误我已经尝试使用该文章中建议的代码,在我的更新方法中将文件夹路径作为文件类型附加到实体,如下所示:
public function editAction(Request $request, Advertiser $advertiser)
{
$advertiser->setLogo(
new File($this->getParameter('logo_directory') .'/' . $advertiser->getLogo())
);
$editForm = $this->createForm(AdvertiserType::class, $advertiser);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('advertiser_list');
}
return $this->render('advertiser/index.html.twig', [
'form' => $editForm->createView()
]);
}
logo_directory 参数已正确定义(并且可以很好地创建新实体)。
如果您有任何想法,请告诉我我做错了什么。
感谢您的帮助。
更新:在这篇文章
->add('file', FileType::class, array('data_class' => null))
所以我现在正在这样做,编辑表单将显示 - 但它不会预先填充之前的选择。
->add('logo', FileType::class, array('data_class' => null), ['label' => 'Logo (JPG or PNG file)'])
有没有想过如何更改它以允许表单显示之前预填充的选择?
设置空 data_class
将删除警告,但它不会起作用,此时您不需要它。
这是因为一旦您的文件被持久化,保留在数据库中的只是一个路径,而不是文件本身(它在磁盘上);
如果要再次编辑此实体,路径(字符串)必须再次转换为文件实体;这就是错误消息所说的。
.. 这就是你写的时候所做的:
$advertiser->setLogo(
new File($this->getParameter('logo_directory') .'/' . $advertiser->getLogo())
);
现在,剩下的问题是您要预填充文件字段。事实上,这是不可能的,因为文件字段指向你自己电脑中的一个位置,而不是你服务器上的文件(而且你不能像那样自动从别人的电脑上传东西,那会很危险).
您想要做的可能是指示文件已存储,获取其路径并可能将其显示给您的用户。
所以在你的 Twig 模板中,类似的东西(更改为你的真实徽标目录):
{% if form.logo.vars.data %}
<img src="{{ asset('/uploads/logos_directory/' ~ form.logo.vars.data.filename) }}"/>
{% endif %}
希望清楚。