【问题标题】:DateTimePicker and Datatransformer, the form render doesnt take the string into accountDateTimePicker 和 Datatransformer,表单渲染不考虑字符串
【发布时间】:2020-01-28 19:01:57
【问题描述】:

我在 Symfony 将 DateTime 转换为字符串时遇到了一些问题。我使用 DataTransformer 来格式化我的日期时间,但在表单中,有一个错误说:“这个值应该是字符串类型”。

这是我的代码: 我的实体:Shift.php(仅必要)

/**
 * @ORM\Id()
 * @ORM\GeneratedValue()
 * @ORM\Column(type="integer")
 */
private $id;
/**
 * @ORM\Column(type="datetime")
 * @Assert\DateTime(message="La date de début doit être au format DateTime")
 */
private $start_at;

我的 ShiftType :

$builder
    ->add('start_at', TextType::class, ['attr' => [ 'class' => 'dateTimePicker']])
    ->add('end_at', TextType::class, ['attr' => [ 'class' => 'dateTimePicker']])
    ->add('has_eat')
    ->add('break_duration')
    ->add('comment')
    ;
$builder->get('start_at')->addModelTransformer($this->transformer);
$builder->get('end_at')->addModelTransformer($this->transformer);

还有我的 DataTransformer:

/**
 * @param DateTime|null $datetime
 * @return string
 */
public function transform($datetime)
{
    if ($datetime === null) 
    {
        return '';
    }
    return $datetime->format('Y-m-d H:i');
}
/**
 * @param string $dateString
 * @return Datetime|null
 */
public function reverseTransform($dateString)
{
    if (!$dateString) 
    {
        throw new TransformationFailedException('Pas de date(string) passé');
        return;
    }
    $date = \Datetime::createFromFormat('Y-m-d H:i', $dateString);
    if($date === false){
        throw new TransformationFailedException("Le format n'est pas le bon (fonction reverseTransform)" . "$dateString");
    }
    return $date;
}

正如我所说,当我要提交表单时,表单有错误。 它说“这个值应该是字符串类型。”它是由以下原因引起的:

Symfony\Component\Validator\ConstraintViolation {#1107 ▼
  root: Symfony\Component\Form\Form {#678 …}
  path: "data.start_at"
  value: DateTime @1578465000 {#745 ▶}
}

有些东西磨损了,当我想编辑班次时,Symfony 从数据库中获取日期并将其转换为没有错误消息的字符串。但是因为我想保存编辑,我遇到了同样的问题

你能帮帮我吗? 谢谢

【问题讨论】:

    标签: symfony bootstrap-datetimepicker data-transform


    【解决方案1】:

    过去我在表单中使用 $this-> 时遇到过类似的问题。

    有时 $this 不会包含当前数据。它可能会解释为什么它一开始会加载,但在提交时,它可能无法正确填写。

    我建议创建一个自定义表单类型以获得更好的可重用性,我知道它工作得很好。

    由于您已经有了 DataTransformer 类,因此您需要创建一个新的自定义表单类型。这种新的表单类型将扩展 TextType 并使用数据转换器。

    例如:

    namespace App\Form\Branch\Type;
    
    use App\Form\Branch\DataTransformer\PhoneFormatTransformer;
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\Extension\Core\Type\TextType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolver;
    
    class PhoneType extends AbstractType
    {
        private $tools;
    
    
        public function __construct()
        {
        }
    
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $transformer = new PhoneFormatTransformer();
            $builder->addModelTransformer($transformer);
        }
    
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults(array());
        }
    
        public function getParent()
        {
            return TextType::class;
        }
    
        public function getBlockPrefix()
        {
            return 'phone';
        }
    }
    

    如果你的服务不是自动装配的,你需要添加一个带有特定标签的服务定义

    App\Form\Branch\Type\PhoneType:
        tags:
        - { name: form.type, alias: phone }
    

    剩下要做的就是在表单构建器中使用新的表单类型:

    use App\Form\Branch\Type\PhoneType;
    ...
    $builder
    ->add('phone', PhoneType::class);
    

    这是一个多一点的工作,但它使它很容易重用,毫无疑问,每次需要日期时间字段时您都必须这样做。

    希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      感谢您的回答。我尝试了旅游解决方案,我会使用它,但这不是我问题的解决方案。使用您的代码,我得到了同样的错误。

      解决方案在实体中。在 start_at 的注释中,我做了一个@Assert/DateTime,它的使用不好。我只是删除了这一行,现在一切都正确了:

      /**
       * @ORM\Column(type="datetime")
       * 
       */
      private $start_at;
      /**
       * @ORM\Column(type="datetime", nullable=true)
       * @Assert\GreaterThan(propertyPath="start_at", message="La date de fin doit être ultérieure...")
       */
      private $end_at;
      

      但是,我使用您的代码,因为它可以重复使用,所以感谢您的贡献

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-10
        • 1970-01-01
        相关资源
        最近更新 更多