Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Symfony 如何使用CollectionType编辑和更新json字符串_Symfony_Twig_Symfony Forms_Symfony 4.3_Data Transform - Fatal编程技术网

Symfony 如何使用CollectionType编辑和更新json字符串

Symfony 如何使用CollectionType编辑和更新json字符串,symfony,twig,symfony-forms,symfony-4.3,data-transform,Symfony,Twig,Symfony Forms,Symfony 4.3,Data Transform,我的数据库中有json字符串。字符串看起来像[{“x”:“1”,“y”:“22”}]。所以基本上它存储了一个点的两个坐标。我希望能够编辑和保存它使用CollectionType表单和数据转换器 这是我的场景实体 namespace App\Entity; use Doctrine\ORM\Mapping as ORM; /** * Scene * * @ORM\Table(name="scenes", indexes={@ORM\Index(name="house_id", colum

我的数据库中有json字符串。字符串看起来像[{“x”:“1”,“y”:“22”}]。所以基本上它存储了一个点的两个坐标。我希望能够编辑和保存它使用CollectionType表单和数据转换器

这是我的场景实体

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Scene
 *
 * @ORM\Table(name="scenes", indexes={@ORM\Index(name="house_id", columns={"house_id"})})
 * @ORM\Entity(repositoryClass="App\Repository\SceneRepository")
 */
class Scene
{
    /**
     * @var int
     *
     * @ORM\Column(name="scene_id", type="bigint", nullable=false, options={"unsigned"=true})
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $sceneId;

    /**
     * @var string
     *
     * @ORM\Column(name="scene_title", type="string", length=50, nullable=false)
     */
    private $sceneTitle;

     /**
     * @var string
     *
     * @ORM\Column(name="points", type="text", length=65535, nullable=false)
     */
    private $points;

    /**
     * Many scenes have one house. This is owing site
     * @ORM\ManyToOne(targetEntity="House", inversedBy="scenes")
     *
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="house_id", referencedColumnName="house_id")
     * })
     */
    private $house;

    /**
     * @return int
     */
    public function getSceneId(): int
    {
        return $this->sceneId;
    }

    /**
     * @return string|null
     */
    public function getSceneTitle(): ?string
    {
        return $this->sceneTitle;
    }

    /**
     * @return string|null
     */
    public function getPoints(): ?string
    {
        return $this->points;
    }

    /**
     * @return House
     */
    public function getHouse(): ?House
    {
        return $this->house;
    }

    /**
     * @param string $sceneTitle
     * @return Scene
     */
    public function setSceneTitle(string $sceneTitle): self
    {
        $this->sceneTitle = $sceneTitle;

        return $this;
    }

    /**
     * @param string $points
     * @return Scene
     */
    public function setPoints(string $points): self
    {
        $this->points = $points;

        return $this;
    }

    /**
     * @param House $house
     * @return Scene
     */
    public function setHouse(House $house): self
    {
        $this->house = $house;

        return $this;
    }
}
这是我的SceneType课程

namespace App\Form;

use App\Entity\Scene;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class SceneType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder
            ->add('sceneTitle')
            ->add('points', CollectionType::class, [
                'entry_type' => PointsEmbededFormType::class,
                'block_name' => 'list',
            ])
            ->add('house');

    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Scene::class,
        ]);
    }

}
我创建了PointSembedFormType

namespace App\Form;

use App\Form\DataTransformer\JsonToInputTransform;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\OptionsResolver\OptionsResolver;
use App\Entity\Scene;

use Symfony\Component\Form\AbstractType;

class PointsEmbededFormType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder->add('points');

        $builder->get('points')->addModelTransformer(new CallbackTransformer(
            function ($pointsJson){
                return json_decode($pointsJson);
            },
            function ($pointsArray){
                return json_encode($pointsArray);
            }
        ))->addViewTransformer(new CallbackTransformer(
            function ($normalizeData){
                $result =[];
                foreach($normalizeData as $item)
                {
                    $result[] =$item->x;
                    $result[] =$item->y;
                }
                return $result;

            },
            function ($viewData) {
                $result = [];
                for ($i=1; $i < count($viewData); $i+2) {

                    $temp['x'] = $viewData[$i];

                    $temp['y'] = $viewData[$i+1];

                    $tempArray = [$temp['x'], $temp['y']];
                    $result[] = json_encode($tempArray);
                }


                return $result;
            }
        ));

    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Scene::class,
        ]);
    }


}
最后是my_form.html.twig

    <ul>
                {% for point in form.points %}

                    <li>
                        {{ form_widget(point) }}
                    </li>
                {% endfor %}
            </ul>
    {form.points%%中的点为%s}
  • {{form_widget(point)}
  • {%endfor%}
我想得到一组输入,为每个点编辑x和y。但我一直得到错误:预期参数类型为“array or(\Traversable and\ArrayAccess)”,给定“string”
似乎错误在树枝上的某个地方。非常感谢您的帮助。

我通过放弃表单中的数据转换器解决了这个问题,因为字段“points”的类型是TextArea,为了显示数组的数据,我需要一个收集类型

因此,在实体“场景”中引入了一个额外的字段“pointsArray”,以及将json转换为数组和将json转换为数组的方法。 方法在SceneControl中被调用,集合类型字段被添加到“pointsArray”属性的表单类型中

    <ul>
                {% for point in form.points %}

                    <li>
                        {{ form_widget(point) }}
                    </li>
                {% endfor %}
            </ul>