我过去曾多次考虑过这一点,所以我想我会记下我曾经/使用过的不同想法。有些东西可能有用,但没有一个是“完美”的 Symfony2 解决方案。
构造函数
在实体中,您可以执行 $this->setBar('default value');但是每次加载实体(db 与否)时都会调用它,并且有点混乱。但是,它适用于每种字段类型,因为您可以创建日期或您需要的任何其他内容。
get 中的 If 语句
我不会,但你可以。
return ( ! $this->hasFoo() ) ? 'default' : $this->foo;
工厂/实例。
调用一个静态函数/二级类,它为您提供一个预先填充了数据的默认实体。例如。
function getFactory() {
$obj = new static();
$obj->setBar('foo');
$obj->setFoo('bar');
return $obj;
}
如果您添加额外的字段,您将不得不维护此功能,这并不理想,但这确实意味着您将数据设置器/默认值与从 db.同样,如果您需要不同的默认数据,您可以拥有多个 getFactories。
扩展/反射实体
创建一个扩展实体(例如 FooCreate extends Foo),它在创建时为您提供默认数据(通过构造函数)。类似于工厂/实例的想法只是一种不同的方法 - 我个人更喜欢静态方法。
在构建表单之前设置数据
在构造函数/服务中,您知道您是否有一个新实体,或者它是否是从数据库中填充的。因此,当您抓取一个新实体时,在不同字段上调用集合数据是合理的。例如。
if( ! $entity->isFromDB() ) {
$entity->setBar('default');
$entity->setDate( date('Y-m-d');
...
}
$form = $this->createForm(...)
表单事件
创建表单时,您在创建字段时设置默认数据。您覆盖此使用 PreSetData 事件侦听器。这样做的问题是您正在复制表单工作量/复制代码并使其更难维护/理解。
扩展形式
类似于 Form 事件,但您根据它是否为 db / new 实体调用不同的类型。我的意思是你有 FooType 定义你的编辑表单, BarType 扩展了 FooType 并将所有数据设置到字段中。然后,在您的控制器中,您只需选择要启动的表单类型。如果您有自定义主题并且喜欢事件,这很糟糕,这会为我的喜好创建过多的维护。
树枝
当您基于每个字段执行此操作时,您也可以使用 value 选项创建自己的主题并默认数据。如果您希望保持模板干净并且表单可重用,那么没有什么能阻止您将其包装到表单主题中。例如
form_widget(form.foo, {attr: { value : default } });
JS
如果字段为空,则使用 JS 函数填充表单很简单。例如,您可以使用占位符做一些事情。这是一个坏主意。
表单即服务
对于我所做的一个基于表单的大型项目,我创建了一个服务,它生成所有表单,完成所有处理等。这是因为表单将在多个环境中的多个控制器中使用,而表单是生成/处理的同样,它们以不同的方式显示/交互(例如错误处理、重定向等)。这种方法的美妙之处在于,您可以默认数据、执行您需要的所有操作、通用处理错误等,所有这些都被封装在一个地方。
结论
正如我所看到的,您会一次又一次地遇到同样的问题——默认数据在哪里?
- 如果您将其存储在 db/doctrine 级别,如果您不想每次都存储默认值会怎样?
- 如果您将其存储在实体级别,如果您想在其他地方重新使用该实体而其中没有任何数据,会发生什么情况?
- 如果您将其存储在实体级别并添加一个新字段,您是否希望以前的版本在编辑时具有该默认值?数据库中的默认设置也是如此...
- 如果您将其存储在表单级别,那么在您以后维护代码时是否显而易见?
- 如果它在构造函数中,如果在多个地方使用表单会发生什么?
- 如果您将其推送到 JS 级别,那么您已经走得太远了 - 数据不应该在视图中,更不用说 JS(我们忽略了兼容性、呈现错误等)
- 如果您像我一样在多个地方使用它,该服务非常棒,但对于一个站点上的简单添加/编辑表单来说,它是多余的...
为此,我每次都以不同的方式处理这个问题。例如,在创建表单之前,可以在构造函数中轻松(并且合乎逻辑地)设置注册表单“newsletter”选项。当我构建链接在一起的表单集合(例如,不同表单类型中的哪些单选按钮链接在一起)时,我使用了事件监听器。当我构建了一个更复杂的实体(例如,一个需要子实体或大量默认数据的实体)时,我使用了一个函数(例如“getFactory”)来根据需要创建它的元素。
我认为没有一种“正确”的方法,因为每次我有这个要求时都会略有不同。
祝你好运!我希望无论如何我已经给了你一些深思熟虑,并且没有过多地闲逛;)