2012-02-27 46 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