Symfony 如何使用CollectionType编辑和更新json字符串
我的数据库中有json字符串。字符串看起来像[{“x”:“1”,“y”:“22”}]。所以基本上它存储了一个点的两个坐标。我希望能够编辑和保存它使用CollectionType表单和数据转换器 这是我的场景实体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
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>