2012-02-27 43 views
3

我在我的Symfony2項目的實體型窗體域。Symfony2的實體領域,顯示所有條目時選用的是空

$builder = $this->createFormBuilder(); 
$projects = $this->getProjects(); 

$builder->add('project', 'entity', 
     array(
      'class' => 'MyBundle:Project', 
      'required' => false, 
      'choices' => $projects, 
     )); 

我遇到的問題是,當getProjects()方法將返回一個空的結果集,在下拉列表中會有在項目表中的所有項目。

有什麼辦法禁用此行爲?

+0

那你想在這個列表中得到什麼?當一個值被設置時它不一樣嗎? – AlterPHP 2012-02-28 09:07:10

回答

5

我相信意外的行爲發生,因爲你是混合起來使用選擇與實體形式的字段類型。

您指定的實體領域(第二個參數$ builder-> Add()方法),然後嘗試與使用「選擇」選項值來填充它。然而,「選擇」選項並不直接適用於Entity field type,雖然它被認爲是從Choice繼承而來。相反,實體字段旨在爲您自動從數據庫加載選項。如果您只設置了實體「類」,則該字段將按照升序主鍵順序與表中的所有實體一起填充。爲了加載一個實體子集和/或以特定的順序加載它們,你可以設置一個'query_builder'函數。

例如,創建升序名稱爲了所有國家的下拉列表:

$builder->add('country', 
       'entity', 
       array('class' => 'My\Bundle\Entity\Country', 
        'property' => 'name', 
        'query_builder' => function(EntityRepository $er) { 
         return $er->createQueryBuilder('country') 
            ->orderBy('country.name', 'ASC'); 
        }, 
        'required' => true, 
        'empty_value' => false)); 

根據需要查詢可以是簡單或複雜。見Using Doctrine's Query Builder

我懷疑在問題中創建項目字段的方式會導致將下拉列表的基礎選項設置兩次 - 首先是在設置了「類」選項時,指向所有可用的項目實體,其次是何時'選項'選項設置爲$ this-> getProjects()的結果。假設後者是一個空陣列,它不會覆蓋前者,因此所有項目都會出現在列表中。

如果由於某種原因,你不能使用查詢生成器來獲得下拉這時你可以手動使用一個選擇字段類型和映射項目的數據爲「選擇」選項項目。例如,像這樣:

$builder = $this->createFormBuilder(); 
$projects = $this->getProjects(); 

$projectChoices = array(); 
foreach ($projects as $project) { 
    $key = $project->getId(); 
    $value = $project->getName(); 
    $projectChoices[$key] = $value; 
} 

$builder->add('project', 
       'choice', 
       array('choices' => $projectChoices, 
        'required' => false)); 

注意,在這種情況下,「項目」字段的值將是一個項目的ID,而實體的領域將是一個實際的項目實體,這是另一個原因最好使用實體字段。

+0

謝謝您的全面回答。 :) 我想我將不得不使用查詢生成器。我認爲你在答案的最後部分犯了一個小錯誤,字段類型應該是「choice」而不是「entity」。 – 2012-02-29 03:36:00

+0

你是對的 - 更新它,謝謝! – redbirdo 2012-02-29 09:20:45

+0

陣列解決方案很好。但是,當表單用於編輯實體時,它將失敗,因爲表單構建器將無法將值設置爲選項列表! – 2012-09-23 21:35:24