在我的模型中,我有一个Recipe实体和Ingredient实体。在配方实体的关系是这样定义的:Symfony表单CollectionType字段的顺序
/**
* @ORM\OneToMany(targetEntity="Ingredient", mappedBy="recipe", cascade={"remove", "persist"}, orphanRemoval=true)
* @ORM\OrderBy({"priority" = "ASC"})
*/
private $ingredients;
中的成分实体:
/**
* @ORM\ManyToOne(targetEntity="Recipe", inversedBy="ingredients")
* @ORM\JoinColumn(name="recipe_id", referencedColumnName="id")
*/
private $recipe;
我的工作CRUD控制器上的食谱,我希望用户能够动态地添加成分。我还希望用户拖放配料以在配方中设置其优先级(顺序)。我为此使用了CollectionType表单字段。
这个页面教程:
http://symfony.com/doc/current/cookbook/form/form_collections.html
添加和配方的表现是完美的,到目前为止的工作,但没有与编辑/更新动作,我会尝试下面描述的一个问题:
在控制器中,我加载实体和创建这样的形式:
public function updateAction($id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$recipe = $em->getRepository('AppBundle:Recipe')->find($id);
$form = $this->createEditForm($recipe);
$form->handleRequest($request);
...
}
由于先验ty保存在数据库中,我有@ORM\OrderBy({"priority" = "ASC"})
,原料的初始加载和显示正常。但是,如果用户拖放配料周围,优先级值会改变。如果存在表单验证错误并且表单需要重复显示,则即使更新了优先级值,表单中的成分也会按旧的顺序显示。
例如,我有以下的初始成分=>的优先级值在DB:
- A => 1
- B => 2
- C => 3
表格行按顺序显示:A,B,C;
用户改变订单后,我有:
- B => 1
- A => 2
- C => 3
但形式行仍显示作为A,B,C;
我知道窗体已经初始化为A,B,C,并且更新priority
不会改变ArrayCollection的元素顺序。但是我几乎不知道如何改变它。
我迄今为止尝试:
$form->getData();
// sort in memory
$form->setData();
这是不行的,因为显然它是不允许上已经有输入表单中使用使用setData()。
我也尝试设置DataTransformer来排序行,但表单忽略新的顺序。
我也尝试在FormType类中使用PRE/POST提交处理程序来排序行,但是表单仍然会忽略新的顺序。
那(种)工作的最后一件事情是这样的:
在配方实体,定义sortIngredients()
方法,它在内存中排序的ArrayCollection,
public function sortIngredients()
{
$sort = \Doctrine\Common\Collections\Criteria::create();
$sort->orderBy(Array(
'priority' => \Doctrine\Common\Collections\Criteria::ASC
));
$this->ingredients = $this->ingredients->matching($sort);
return $this;
}
然后,控制器:
$form = $this->createEditForm($recipe);
$form->handleRequest($request);
$recipe->sortIngredients();
// repeatedly create and process form with already sorted ingredients
$form = $this->createEditForm($recipe);
$form->handleRequest($request);
// ... do the rest of the controller stuff, flush(), etc
这个工程,但形式创建和处理两次,老实说,它看起来像一个黑客...
我在寻找更好的方法来解决问题。
作品!花了半天的时间...谢谢你。太糟糕了,Symfony网站上关于这种方法的文档并不多。 – Karolis