Symfony2实体字段类型替代“property”或“__toString()”?

时间:2012-03-28 21:32:17

标签: forms symfony symfony-forms

使用Symfony2 entity field type应指定property选项:

$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);
    }
}

后者的不足之处在于,强制在所有表单中以相同的方式显示实体

还有其他方法可以让它更灵活吗? 我的意思是类似回调函数:

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

3 个答案:

答案 0 :(得分:41)

我发现这非常有用,我用一个非常简单的方法用你的代码做到这一点,所以这里是解决方案

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

在类Customer(实体)

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

呃瞧:D属性从实体而不是数据库中获取其字符串。

答案 1 :(得分:3)

传递闭包不起作用,但很快就会被添加到Symfony:https://github.com/symfony/symfony/issues/4067

答案 2 :(得分:1)

似乎可以通过在ObjectChoiceList.phpelseif ($this->labelPath)阻止后添加以下阻止来实现这一目标。

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

虽然没试过:)。