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

Posted

技术标签:

【中文标题】Symfony2 实体字段类型替代“property”或“__toString()”?【英文标题】:Symfony2 entity field type alternatives to "property" or "__toString()"? 【发布时间】:2012-04-12 13:04:05 【问题描述】:

使用 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);
     ,
));

【问题讨论】:

我遇到了同样的情况,并计划很快在 SO 上发布一个问题......我期待着答案。 【参考方案1】:

我发现这真的很有帮助,我用你的代码找到了一个非常简单的方法,所以这里是解决方案

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

在类客户(实体)中

public function getLabel()

    return $this->lastname .', '. $this->firstname .' ('. $this->email .')';

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

【讨论】:

您可能应该使用 getter 而不是直接访问这些值。 return $this->getLastname() .', '. $this->getFirstname() .' ('. $this->getEmail() .')'; 这很好,除非您需要生成缩略图或无法从模型中执行的操作...【参考方案2】:

目前还不能传递闭包,但很快就会添加到 Symfony 中:https://github.com/symfony/symfony/issues/4067

【讨论】:

hm...但是对于实体表单类型的闭包没有任何说明。【参考方案3】:

看来这可以通过在ObjectChoiceList.php 中的elseif ($this->labelPath) 块之后添加以下块来实现。

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

虽然没试过:)。

【讨论】:

这看起来确实可行,但需要破解 Symfony。如果可能的话,我宁愿避免这种情况。当然,有一种“正确”的方法可以做到这一点。在我看来,这是一个相当重要的问题。 嗯,这是 AFIK 的唯一方法。要使其进入 Symfony2 核心,需要将 PR 发送到 github。如果我有空闲时间,我可以提交带有适当单元测试的 PR。如果有谁提交一个PR也不错。 @m2mdas 如果您确实提交了 PR,请告诉我们。我现在并没有因为这个功能而受到伤害,但我会在某个时候,如果到那时其他人还没有处理这个问题,我可能会自己做。

以上是关于Symfony2 实体字段类型替代“property”或“__toString()”?的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 表单 > 实体字段类型 > 查询构建器 > 可能的子选择?

Symfony2 生成带有选项的实体字段

Symfony2 和 Selectize.js:在实体字段类型中保留新项目的最清晰方法?

Symfony2 将自定义字段添加到表单构建器

Symfony2 - 向现有实体添加新字段

Symfony2:字段或鉴别器列映射中实体上列“id”的重复定义