Mic*_*ick 13 php doctrine symfony-forms symfony doctrine-orm
可以存储数组而不是映射的关联.在Symfony2中,使用集合字段类型相当容易.例如,使用此技术,您可以存储填充数组事件字段的文本字段数组.然而,为了更新数组,有一个技巧,这个技巧由@Vadim Ashikhman在接受的答案中精美地解释.
有时,存储数组而不是映射关联是有用且更有效的.但是,一旦创建,如果该数组的大小没有改变,更新此数组仍然很复杂?
许多人都有类似的问题,但没有人找到解决这个问题的正确方法.

团队可以组织许多活动.这些事件只是使用Doctrine而不是使用OneToMany关联存储在数组中.因此,实体事件不与Doctrine映射.
<?php
namespace Acme\TestBundle\Entity;
...
class Event
{
/**
* @Assert\NotBlank
*/
private $name;
public function setName($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}
Run Code Online (Sandbox Code Playgroud)
<?php
namespace Acme\TestBundle\Entity;
...
/**
* @ORM\Entity()
* @ORM\HasLifecycleCallbacks
* @ORM\Table(name="teams")
*/
class Team
{
/**
* @ORM\Column(type="array")
* @var array
*/
protected $events;
public function addEvent($event)
{
if (!in_array($event, $this->events, true)) {
$this->events[] = $event;
}
return $this;
}
public function removeEvent($event)
{
if (false !== $key = array_search($event, $this->events, true)) {
unset($this->events[$key]);
$this->events = array_values($this->events);
}
return $this;
}
public function getEvents()
{
return $this->events;
}
public function setEvents(array $events)
{
$this->events = array();
foreach ($events as $event) {
$this->addEvent($event);
}
return $this;
}
Run Code Online (Sandbox Code Playgroud)
<?php
namespace Acme\TestBundle\Form\Type;
...
class EventType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->add('name', 'text');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\TestBundle\Entity\Event',
'cascade_validation' => true,
));
}
...
}
Run Code Online (Sandbox Code Playgroud)
<?php
namespace Acme\TestBundle\Form\Type;
...
class TeamType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->add('events','collection', array(
'type' => new EventType(),
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'by_reference' => false,
'options' => array('data_class' => 'Acme\TestBundle\Entity\Event'),
)
);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\TestBundle\Entity\Team',
));
}
...
}
Run Code Online (Sandbox Code Playgroud)
/**
* Update a team
*
* @Route("update/{team_id}", name="updateTeamFromId")
* @Template("AcmeTestBundle:Team:teamUpdate.html.twig")
*/
public function updateTeamAction($team_id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$repository= $em->getRepository('AcmeTestBundle:Team');
$team_to_update = $repository->find($team_id);
$form = $this->createForm(new teamType(), $team_to_update);
if ($request->getMethod() == 'POST')
{
$form->bind($request);
if ($form->isValid()){
$em->persist($team_to_update);
$em->flush();
return $this->redirect($this->generateUrl('homepage')) ;
}
}
return array(
'form' => $form->createView(),
'team_id' => $team_id,
);
}
Run Code Online (Sandbox Code Playgroud)
Vad*_*man 13
你可以在这里找到答案:
参考文献:
Doctrine使用相同的运算符
===来比较旧值和新值之间的变化.在具有不同数据的同一对象上使用的运算符始终返回true.还有另一种方法可以解决此问题,您可以克隆需要更改的对象.Run Code Online (Sandbox Code Playgroud)$items = $myEntityObject->getItems(); $items[0] = clone $items[0]; $items[0]->setSomething(123); $myEntityObject->setItems($items);或者更改setItems()方法
Run Code Online (Sandbox Code Playgroud)public function setItems($items) { if (!empty($items) && $items === $this->items) { reset($items); $key = key($items); $items[$key] = clone $items[$key]; } $this->items = $items; }
您可以在控制器内尝试此操作:
public function updateTeamAction($team_id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$repository= $em->getRepository('AcmeTestBundle:Team');
$team_to_update = $repository->find($team_id);
$form = $this->createForm(new teamType(), $team_to_update);
if ($request->getMethod() == 'POST')
{
$form->bind($request);
if ($form->isValid()){
$events = $team_to_update->getEvents();
foreach($events as $key => $value){
$team_to_update->removeEvent($key);
}
$em->flush();
$team_to_update->setEvents($events);
$em->persist($team_to_update);
$em->flush();
return $this->redirect($this->generateUrl('homepage')) ;
}
}
return array(
'form' => $form->createView(),
'team_id' => $team_id,
);
}
Run Code Online (Sandbox Code Playgroud)
可能有更好的方法来做到这一点,我知道这不是一个好方法,但在您(或其他人)找到解决方案之前,您可以使用它作为临时修复。
| 归档时间: |
|
| 查看次数: |
11533 次 |
| 最近记录: |