2012-03-28 138 views
17

使用Symfony2的entity field type一个应该指定property选项:Symfony2实体字段类型替代“属性”或“__toString()”?

$builder->add('customers', 'entity', array(
    'multiple' => true, 
    'class' => 'AcmeHelloBundle:Customer', 
    'property' => 'first', 
)); 

但有时这是不够的:想想两个客户具有相同的名称,所以显示电子邮件(独特)将是强制性的。

另一种可能性是实施__toString()到模型:

class Customer 
{ 
    public $first, $last, $email; 

    public function __toString() 
    { 
     return sprintf('%s %s (%s)', $this->first, $this->last, $this->email); 
    } 
} 

后者的disadvances是你被迫显示实体所有的形式以同样的方式

还有其他方法可以使这更灵活吗?我的意思是这样一个回调函数:

$builder->add('customers', 'entity', array(
    'multiple' => true, 
    'class' => 'AcmeHelloBundle:Customer', 
    'property' => function($data) { 
     return sprintf('%s %s (%s)', $data->first, $data->last, $data->email); 
    }, 
)); 
+0

我有此相同的情况,并计划张贴在这么快的一个问题...我期待回答。 – Icode4food 2012-03-28 22:44:43

回答

40

我发现这真的有帮助的,我咬咬牙一个非常简单的方式与您的代码,这样做,所以这里是解决方案

$builder->add('customers', 'entity', array(
'multiple' => true, 
'class' => 'AcmeHelloBundle:Customer', 
'property' => 'label', 
)); 

而且在类客户(实体)

public function getLabel() 
{ 
    return $this->lastname .', '. $this->firstname .' ('. $this->email .')'; 
} 

eh voila:D属性从实体中获取它的字符串而不是数据库。

+6

您应该使用getters并且不直接访问值。 'return $ this-> getLastname()。','。 $ this-> getFirstname()。' ('。$ this-> getEmail()'')';' – 2013-05-03 11:18:37

+0

这很好,除非你需要生成缩略图或者你无法从模型中做的事情...... – darkbluesun 2015-07-17 05:10:09

1

看来这可能是由后ObjectChoiceList.phpelseif ($this->labelPath)块添加以下块实现的。

elseif (is_callable($this->labelPath)) { 
    $labels[$i] = call_user_func($this->labelPath, $choice); 
} 

虽然没有尝试过:)。

+1

这看起来确实可行,但需要黑客Symfony。如果可能,我宁愿避免这种情况。当然有一个“正确”的方法来做到这一点。在我看来,这是一个相当重要的问题。 – Icode4food 2012-03-29 12:14:59

+0

@ Icode4food同意。 – gremo 2012-03-29 14:12:38

+0

那么这是AFIK的唯一途径。为了使它成为Symfony2核心,PR需要发送给github。如果我有空闲时间,我可以提交适当的单元测试。如果任何人提交的PR也很好。 – 2012-03-29 14:47:28