2013-01-31 65 views
1

我想更新多個實體和更新我想添加一個名爲「評論」的字段。該字段與實體無關;我會將評論保存在一個單獨的表格中。Symfony形式,子/嵌入形式

這是我試過(以下控制器代碼) - 這僅僅是一個代碼的樣本,但應該給的什麼,我試圖做一個想法:

$form = $this->createFormBuilder(); 

foreach (array(1,2,3) as $id) { 
    $subform = $this->createFormBuilder() 
     ->add('story', 'entity', array(
      'class' => 'AcmeDemoBundle:Story', 
      'query_builder' => function($em) use ($id) { 
       $qb = $em->createQueryBuilder('s') 
       $qb->select(array('j')) 
        ->add('from', 'AcmeDemoBundle:Story') 
        ->addWhere('j.id = :id') 
        ->setParameter('id', $id); 
       return $qb; 
      }, 
      'property' => 'id', 
      'required' => true, 'expanded' => true, 'multiple' => true 
     ) 
     ->add('comment', 'textarea'); 
} 
$form->add($subform, '', array('label' => ''); 

... 
// then I send the form to the template with $form->createView() 

我預計會看到一個表單,每個實體(1,2,3)都是一個複選框,並在該註釋塊旁邊。相反,我只會得到一個複選框和一個註釋,並且總是針對數組中的最後一個實體(在上述情況下爲實體編號3)。看起來,表單構建器忽略了我添加的所有子表單,只是最後一個 - 當查看到達數據庫的SQL時,情況也是如此,只有#3的選擇和1和1的選擇2.

由於生成的HTML支持什麼,我試圖做的,我希望上面的工作:

<input type="checkbox" id="form_form_story_0" name="form[form][story][]" value="3"> 
<textarea id="form_form_comment" name="form[form][comment] /> 

我也試過給人領域唯一的名稱 - 例如 - >添加( 'story_'。$ id)等等,但是沒有做任何事情。我也嘗試給每個querybuilder一個唯一的名稱$ em-> createQueryBuilder('s'。$ id),但是這也不起作用。它似乎並不有什麼做的實體,即使我嘗試:

另外,如果我刪除query_builder(只需要使用類)

更新它不工作創建子表單以及純文本字段不起作用......

更新2如果子窗體有使用不同的名稱:

$subForm = $this->get('form.factory')->createNamedBuilder("form$id"), 'form', array()) 

然後它工作。不幸的是,這意味着我無法循環樹枝內的子表單。

回答

0

它不能像上面陳述/詢問的那樣工作。

->add 

覆蓋這個孩子以前的副本,因爲在這裏看到:

Symfony\Component\Form 
... 
public function add(FormInterface $child) 
... 
$this->children[$child->getName()] = $child; 

「解決」我丟棄的子表單的理念問題,並分別命名爲每個項目是這樣的:

$form 
... 
->add("comment_$id", 'textarea') 

製作了一個實體的數組,並在樹枝中呈現該實體的註釋字段,如下所示:

{% for entity in entities %} 
... 
{% set child = "comment_" ~ entity.id %}{{ form_widget(form.children[child]) }} 
... 
0
  1. 你的示例代碼中包含的錯誤:你添加$子窗體週期,這樣你就明確地將只剩下最後產生$子對象。

  2. 注意的行$this->children[$child->getName()] = $child;從「簡單」的方法防止添加子窗體的建設者,但有一個解決辦法:

與其說$this->createFormBuilder()幫手子窗體的(這將給它的名字「形式」),您可以使用明確的名稱與$this->container->get('form.factory')->createNamedBuilder('sub_form_1')創建biulder。

+0

順便說一句,當調用使用FormBuilder實例添加時,它會忽略所有其他參數,有點重載php方式。 – alpaca