如何正确地将日期转换为字符串并以 symfony 形式返回,以便可以使用日期选择器
how to properly transform date to string and back in symfony form so can use date picker
在我的 Symfony 4 应用程序中,我有一个包含日期类型字段的实体。默认情况下,Symfony 将其呈现为一组 select 框,代表月、日、年。我已将其更改为文本小部件,以便我可以使用 jQuery UI 日期选择器。
但是我 运行 在尝试提交表单时遇到了问题。
这是我实体上的字段:
/**
* @ORM\Column(type="date")
*/
private $start_date;
这是我显示字段的方式:
$builder->add('start_date', DateType::class, [
'widget' => 'single_text',
// prevents rendering it as type="date", to avoid HTML5 date pickers
'html5' => false,
// adds a class that can be selected in JavaScript
'attr' => ['class' => 'js-datepicker'],
])
我的页面上有 jquery 和 jqueryui,这允许显示日期选择器。
以下是我目前正在尝试将日期转换为字符串的方法,反之亦然。目前,我只是尝试使用硬编码日期,当然,一旦我知道我在做什么,我就会更改它。
$builder->get('start_date')
->addModelTransformer(new CallbackTransformer(
function ( $dateAsString ) {
return new \DateTime('2019-01-01');
},
function ( $dateAsDate ) {
return '2019-01-01';
}
));
提交表单产生此错误:
给定 "DateTimeInterface"、"string" 类型的预期参数。
有没有人知道如何在我的实体中将日期存储为日期类型,同时在我的表单中将其显示为字符串?
我邀请您查看 documentation of DateType
。您会发现您可以根据 input
选项以多种格式存储日期:
- 字符串(例如 2011-06-05)
- datetime(一个 DateTime 对象)
- datetime_immutable(一个 DateTimeImmutable 对象)
- 数组(例如 ['year' => 2011,'month' => 06,'day' => 05])
- 时间戳(例如 1307232000)
这是您实体中的基础 model value
。在您的示例中,您必须选择默认值 datetime
。
您为 widget
选项做出了正确的选择 - single_text
。不要忘记设置一个正确的format
。这是view value
。
在您的情况下,您不需要编写自己的数据转换器。 Symfony 会负责将 model value
转换为 view value
,反之亦然。它通过 normalised value
:
使用
`model data`(string, datetime, timestamp, etc.) -> `norm data` (`DateTime`) -> `view data` (string for widget=single_text, array for widget=choice)
和
`view data` (string for widget=single_text, array for widget=choice) -> `norm data` (`DateTime`) -> `model data`(string, datetime, timestamp, etc.)
虽然 view data
和 model data
的格式不同,但 norm data
的格式始终相同 - DateTime
。您添加的模型转换器返回 string
以设置为规范化数据。这就是你出错的原因。
您可以将预定义格式添加到您的表单生成器中,就像这样
'widget' => 'single_text',
//default format of the date
'format' => 'yyyy-MM-dd',
// prevents rendering it as type="date", to avoid HTML5 date pickers
'html5' => false,
// adds a class that can be selected in JavaScript
'attr' => ['class' => 'js-datepicker'],
])
在这种情况下您不需要转换器,formbuilder 会处理它。
在我的 Symfony 4 应用程序中,我有一个包含日期类型字段的实体。默认情况下,Symfony 将其呈现为一组 select 框,代表月、日、年。我已将其更改为文本小部件,以便我可以使用 jQuery UI 日期选择器。
但是我 运行 在尝试提交表单时遇到了问题。
这是我实体上的字段:
/**
* @ORM\Column(type="date")
*/
private $start_date;
这是我显示字段的方式:
$builder->add('start_date', DateType::class, [
'widget' => 'single_text',
// prevents rendering it as type="date", to avoid HTML5 date pickers
'html5' => false,
// adds a class that can be selected in JavaScript
'attr' => ['class' => 'js-datepicker'],
])
我的页面上有 jquery 和 jqueryui,这允许显示日期选择器。
以下是我目前正在尝试将日期转换为字符串的方法,反之亦然。目前,我只是尝试使用硬编码日期,当然,一旦我知道我在做什么,我就会更改它。
$builder->get('start_date')
->addModelTransformer(new CallbackTransformer(
function ( $dateAsString ) {
return new \DateTime('2019-01-01');
},
function ( $dateAsDate ) {
return '2019-01-01';
}
));
提交表单产生此错误: 给定 "DateTimeInterface"、"string" 类型的预期参数。
有没有人知道如何在我的实体中将日期存储为日期类型,同时在我的表单中将其显示为字符串?
我邀请您查看 documentation of DateType
。您会发现您可以根据 input
选项以多种格式存储日期:
- 字符串(例如 2011-06-05)
- datetime(一个 DateTime 对象)
- datetime_immutable(一个 DateTimeImmutable 对象)
- 数组(例如 ['year' => 2011,'month' => 06,'day' => 05])
- 时间戳(例如 1307232000)
这是您实体中的基础 model value
。在您的示例中,您必须选择默认值 datetime
。
您为 widget
选项做出了正确的选择 - single_text
。不要忘记设置一个正确的format
。这是view value
。
在您的情况下,您不需要编写自己的数据转换器。 Symfony 会负责将 model value
转换为 view value
,反之亦然。它通过 normalised value
:
`model data`(string, datetime, timestamp, etc.) -> `norm data` (`DateTime`) -> `view data` (string for widget=single_text, array for widget=choice)
和
`view data` (string for widget=single_text, array for widget=choice) -> `norm data` (`DateTime`) -> `model data`(string, datetime, timestamp, etc.)
虽然 view data
和 model data
的格式不同,但 norm data
的格式始终相同 - DateTime
。您添加的模型转换器返回 string
以设置为规范化数据。这就是你出错的原因。
您可以将预定义格式添加到您的表单生成器中,就像这样
'widget' => 'single_text',
//default format of the date
'format' => 'yyyy-MM-dd',
// prevents rendering it as type="date", to avoid HTML5 date pickers
'html5' => false,
// adds a class that can be selected in JavaScript
'attr' => ['class' => 'js-datepicker'],
])
在这种情况下您不需要转换器,formbuilder 会处理它。