在我的模型中,我有一個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