Symfony 4 - 无法转换 属性 路径“[myDateTime]”的值:需要一个 \DateTimeInterface
Symfony 4 - Unable to transform value for property path "[myDateTime]": Expected a \DateTimeInterface
我想使用 Symfony 表单呈现日期时间选择器。
由于日期时间选择器只需要输入文本(因为它 returns 是一个简单的字符串),我决定使用 DataTransformers 表单将数据从日期时间转换为字符串,反之亦然。
但是当我尝试呈现我的页面时,我收到以下错误消息:
Unable to transform value for property path "[myDateTime]": Expected a \DateTimeInterface.
我的控制器class如下:
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\Request;
/**
* Class HomeController
* @package App\Controller
*/
class HomeController extends Controller
{
/**
* @Route("/test", name="form_test")
*/
public function testForm(Request $request)
{
$data = ['myDateTime' => new \DateTime()];
$builder = $this->createFormBuilder($data)
->add('myDateTime', DateTimeType::class, ['label' => 'My datetime']);
$builder
->get('myDateTime')
->addModelTransformer(new DateTimeToStringTransformer(null, null, 'd/m/Y H:i'));
$form = $builder->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
dump($form->getData());
}
return $this->render('test.html.twig', [
'form' => $form->createView(),
]);
}
}
我的视图模板就是这么简单:
{% extends 'base.html.twig' %}
{% block body %}
{{ form_start(form) }}
{{ form_widget(form) }}
<button class="btn btn-success">{{ button_label|default('Send') }}</button>
{{ form_end(form) }}
{% endblock %}
为了呈现我的日期时间选择器,我使用了存储在 form/fields.html.twig:
中的表单主题
{% use "bootstrap_4_layout.html.twig" %}
{% block datetime_row %}
<div class="form-group">
{{ form_label(form) }}
{{ form_errors(form) }}
{{ form_widget(form) }}
{{ form_help(form) }}
</div>
{% endblock %}
{% block datetime_widget %}
<div class="input-group date" id="{{ id }}" data-target-input="nearest">
<input type="text" class="form-control datetimepicker-input" data-toggle="datetimepicker" data-target="#{{ id }}" {% if value %}value="{{ value|e('html_attr') }}"{% endif %}/>
<div class="input-group-append" data-target="#{{ id }}" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
{% endblock datetime_widget %}
并将此主题添加到 twig.yaml 配置文件中:
twig:
paths: ['%kernel.project_dir%/templates']
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
form_themes:
- 'bootstrap_4_layout.html.twig'
- 'form/fields.html.twig'
有没有人帮助我理解为什么这不起作用或我做错了什么?
为了让您的表单正常工作,您必须在 myDateTime
字段中使用 TextType
而不是 DateTimeType
:
$builder = $this->createFormBuilder($data)
->add('myDateTime', TextType::class, ['label' => 'My datetime']);
解释:
Symfony 默认为 DateTimeType
字段添加 DataTransformerChain
类型的 ViewTransformer
。此转换器在 Form
class 中的 normToView
函数内部调用,并需要 \DateTime
class 的参数。但是,通过添加 DateTimeToStringTransformer
类型的 ModelTransformer,您已经将 myDateTime
字段的规范化值更改为字符串,这就是您收到错误的原因。
此外,即使您使用
,您的代码也无法正常工作
->addViewTransformer(new DateTimeToStringTransformer(null, null, 'd/m/Y H:i'));
而不是
->addModelTransformer(new DateTimeToStringTransformer(null, null, 'd/m/Y H:i'));
因为在这种情况下,DataTransformerChain
转换器在您添加的转换器之前被调用,您将得到相同的错误,这次来自 DateTimeToStringTransformer
。
您不需要 DateTimeToStringTransformer
。删除此变压器。默认情况下,Symfony DateTimeType
需要一个 \DateTime
对象。
所以发生的事情是你的转换器正在将它转换为一个字符串,然后 DateTimeType
期待一个 DateTime
但它得到的是一个字符串所以它导致了这个错误。
您可以在此处阅读更多内容:https://symfony.com/doc/current/reference/forms/types/datetime.html#input
我想使用 Symfony 表单呈现日期时间选择器。
由于日期时间选择器只需要输入文本(因为它 returns 是一个简单的字符串),我决定使用 DataTransformers 表单将数据从日期时间转换为字符串,反之亦然。 但是当我尝试呈现我的页面时,我收到以下错误消息:
Unable to transform value for property path "[myDateTime]": Expected a \DateTimeInterface.
我的控制器class如下:
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\Request;
/**
* Class HomeController
* @package App\Controller
*/
class HomeController extends Controller
{
/**
* @Route("/test", name="form_test")
*/
public function testForm(Request $request)
{
$data = ['myDateTime' => new \DateTime()];
$builder = $this->createFormBuilder($data)
->add('myDateTime', DateTimeType::class, ['label' => 'My datetime']);
$builder
->get('myDateTime')
->addModelTransformer(new DateTimeToStringTransformer(null, null, 'd/m/Y H:i'));
$form = $builder->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
dump($form->getData());
}
return $this->render('test.html.twig', [
'form' => $form->createView(),
]);
}
}
我的视图模板就是这么简单:
{% extends 'base.html.twig' %}
{% block body %}
{{ form_start(form) }}
{{ form_widget(form) }}
<button class="btn btn-success">{{ button_label|default('Send') }}</button>
{{ form_end(form) }}
{% endblock %}
为了呈现我的日期时间选择器,我使用了存储在 form/fields.html.twig:
中的表单主题{% use "bootstrap_4_layout.html.twig" %}
{% block datetime_row %}
<div class="form-group">
{{ form_label(form) }}
{{ form_errors(form) }}
{{ form_widget(form) }}
{{ form_help(form) }}
</div>
{% endblock %}
{% block datetime_widget %}
<div class="input-group date" id="{{ id }}" data-target-input="nearest">
<input type="text" class="form-control datetimepicker-input" data-toggle="datetimepicker" data-target="#{{ id }}" {% if value %}value="{{ value|e('html_attr') }}"{% endif %}/>
<div class="input-group-append" data-target="#{{ id }}" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
{% endblock datetime_widget %}
并将此主题添加到 twig.yaml 配置文件中:
twig:
paths: ['%kernel.project_dir%/templates']
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
form_themes:
- 'bootstrap_4_layout.html.twig'
- 'form/fields.html.twig'
有没有人帮助我理解为什么这不起作用或我做错了什么?
为了让您的表单正常工作,您必须在 myDateTime
字段中使用 TextType
而不是 DateTimeType
:
$builder = $this->createFormBuilder($data)
->add('myDateTime', TextType::class, ['label' => 'My datetime']);
解释:
Symfony 默认为 DateTimeType
字段添加 DataTransformerChain
类型的 ViewTransformer
。此转换器在 Form
class 中的 normToView
函数内部调用,并需要 \DateTime
class 的参数。但是,通过添加 DateTimeToStringTransformer
类型的 ModelTransformer,您已经将 myDateTime
字段的规范化值更改为字符串,这就是您收到错误的原因。
此外,即使您使用
,您的代码也无法正常工作->addViewTransformer(new DateTimeToStringTransformer(null, null, 'd/m/Y H:i'));
而不是
->addModelTransformer(new DateTimeToStringTransformer(null, null, 'd/m/Y H:i'));
因为在这种情况下,DataTransformerChain
转换器在您添加的转换器之前被调用,您将得到相同的错误,这次来自 DateTimeToStringTransformer
。
您不需要 DateTimeToStringTransformer
。删除此变压器。默认情况下,Symfony DateTimeType
需要一个 \DateTime
对象。
所以发生的事情是你的转换器正在将它转换为一个字符串,然后 DateTimeType
期待一个 DateTime
但它得到的是一个字符串所以它导致了这个错误。
您可以在此处阅读更多内容:https://symfony.com/doc/current/reference/forms/types/datetime.html#input