我按照文档使用DataMapper:https://symfony.com/doc/current/form/data_mappers.html 从表单中的3个字段中的1个更新日期:
表格类
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('period_start_daily', DateType::class, [
'widget' => 'single_text',
'label' => 'Day',
'html5' => false,
'attr' => ['class' => 'js-datepicker'],
'mapped' => false,
'required' => false
])
->add('period_start_weekly', DateType::class, [
'widget' => 'single_text',
'label' => 'Week',
'html5' => false,
'attr' => ['class' => 'js-datepicker'],
'mapped' => false,
'required' => false
])
->add('period_start_monthly', ChoiceType::class, [
'required' => true,
'label' => 'Month',
'choice_loader' => new CallbackChoiceLoader(function () {
$months = [];
for ($i = 0; $i <= 12; $i++) {
$month = strtotime('first day of this month + ' . $i . ' months');
$months[date('M Y', $month)] = date('Y-m-d', $month);
}
return $months;
}),
'mapped' => false,
'required' => false
])
...
$builder
->setDataMapper($this);
...
public function mapFormsToData($forms, &$data)
{
/** @var FormInterface[] $forms */
$forms = iterator_to_array($forms);
switch (intval($forms['Type']->getViewData())){
case 1:
$start = $forms['period_start_daily']->getNormData();
$end = clone $start;
break;
case 2:
$start = $forms['period_start_weekly']->getNormData();
$end = clone $start;
$end->add(new \DateInterval('P6D'));
break;
case 3:
$start = $forms['period_start_daily']->getNormData();
$end = (new \DateTime(
strtotime($this->getData()['period_start_monthly']->format('Y-m-d').' last day of month')
));
break;
}
$data = (new DataSet())
->setPeriodStart($start)
->setPeriodEnd($end)
->setType($forms['Type']->getNormData())
->setUpload($forms['upload']->getNormData());
Run Code Online (Sandbox Code Playgroud)
调节器
$form = $this->createForm(DataSetType::class, $dataset);
$form->handleRequest($request->getCurrentRequest());
if ($form->isSubmitted() && $form->isValid()){
$dataset
->setPeriodStart($form->getNormData()->getPeriodStart())
->setPeriodEnd($form->getNormData()->getPeriodEnd());
$dataset->setType($form->getNormData()->getType());
$dataset->setActive(false);
$dataset->setUpload($form->getNormData()->getUpload());
$dataset->getPeriodStart()->setTime(0, 0, 0);
$dataset->getPeriodEnd()->setTime(0, 0, 0);
$em->persist($dataset);
$em->flush();
Run Code Online (Sandbox Code Playgroud)
我希望DataMapper直接更新我的对象,但是我仍然需要复制来自$ form-> getNormData()的数据.
Symfony版本是4.2
我下载了你的项目来调试它,我发现了一个错误 - 很难检测到:)我开始认为 Symfony 4 可能有问题,但事实并非如此。一切都很好,一切都很好。
\n\n看:
\n\n\n\n\n\n\nspl_object_hash \xe2\x80\x94 返回给定对象的哈希 ID
\n\n该函数返回对象的唯一标识符。这个id可以用作存储对象的散列键,或者用于标识对象,只要该对象不被破坏。一旦对象被销毁,它的哈希值就可以被其他对象重用。
\n
$beforeHash并且$afterHash具有不同的值 - 因此,它不是同一个对象
在DataSetType.php(第 138 行)中,您创建了DataSet一个丢失对作为第二个参数传递的先前对象的引用的新实例mapFormsToData:
您应该修改$data参数中的对象,而不是创建 的新实例DataSet。
步骤1:
\n\n更改此代码:
\n\n$data = (new DataSet())\n ->setPeriodStart($start)\n ->setPeriodEnd($end)\n ->setType($forms[\'Type\']->getNormData())\n ->setUpload($forms[\'upload\']->getNormData())\n ->setActive($forms[\'active\']->getNormData())\n ;\nRun Code Online (Sandbox Code Playgroud)\n\n对于这段代码:
\n\n$data->setPeriodStart($start)\n ->setPeriodEnd($end)\n ->setType($forms[\'Type\']->getNormData())\n ->setUpload($forms[\'upload\']->getNormData())\n ->setActive($forms[\'active\']->getNormData());\nRun Code Online (Sandbox Code Playgroud)\n\n第2步:
\n\n从控制器中删除不必要的代码。create方法应该如下所示:
public function create(RequestStack $request)\n{\n $dataset = new DataSet();\n\n $form = $this->createForm(DataSetType::class, $dataset);\n\n $form->handleRequest($request->getCurrentRequest());\n\n if ($form->isSubmitted() && $form->isValid()){\n $em = $this->getDoctrine()->getManager();\n $em->persist($dataset);\n $em->flush();\n\n if ($dataset->getUpload()) {\n $em->getRepository(\'App:DataSet\')\n ->disableUploadOthers($dataset->getId(), $dataset->getType());\n }\n $this->addFlash(\'success\', \'Dataset created.\');\n return $this->redirectToRoute(\'dataset_index\');\n }\n\n return $this->render(\'dataset/create.html.twig\', [\n \'form\' => $form->createView()\n ]);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n中的值$dataset必须在没有您帮助的情况下更改:)
顺便说一句 - 最好扩展文档并展示 DataMapper 如何与 Doctrine 模型一起工作......
\n