symfony render json_array entity type and save usi

2019-07-14 21:19发布

问题:

Imagine I have an Article entity.
And in this entity have a report attribute which is an json_array type.

Json_array's data may like
{"key1":"value1","key2":{"k1":"v1","k2","v2"...},"key3":["v1","v2","v3"...]...}.
I mean the json_array may contains simple key:value
or the value may also contains key:vaule
or the value may an array.

Now I don't know how to use symfony form to render and save these json_array like other normal attribute(e.g.,title).
At the same time,I want to manage the key label name with an meaning name just like change the title field's label.
How to achieve this,I feel very difficult.

class Article
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="title", type="string", length=255)
     */
    private $title;

    /**
     * @var array
     *
     * @ORM\Column(name="report", type="json_array")
     */
    private $report;

}

回答1:

Maybe you can use json_decode to pass from json to array and later in the form you can use:

 ->add('someField', null, array('mapped' => false))

And in the success do something with this values

$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// some awesome code here
}

Hope this can help you.

Roger



回答2:

you can create a data type to manage your report field :

namespace Acme\TestBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

    class ReportType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('key1',TextType::class,array('label' => 'K1'))
                ->add('key2',TextType::class,array('label' => 'K2'))
            ;
        }

        public function getName()
        {
            return 'report';
        }
    }

Then declare the new data type :

# src/Acme/TestBundle/Resources/config/services.yml
services:
    acme_test.form.type.report:
        class: Acme\TestBundle\Form\Type\ReportType
        tags:
            - { name: form.type, alias: report }

And finally use this new dataType in your form :

->add('reports',
            'collection',
            array(
                'type'=>'report',
                'prototype'=>true,
                'allow_add'=>true,
                'allow_delete'=>true,
                'options'=>array(
                )
            )
        )