codete / form-generator-bundle
Symfony 动态表单生成 Bundle
Requires
- php: ^7.1
- doctrine/annotations: ~1.2
- doctrine/instantiator: ^1.0
- symfony/form: ~3.4|~4.0
- symfony/framework-bundle: ~3.4|~4.0
Requires (Dev)
- phpunit/phpunit: ^6.4
- symfony/expression-language: ~3.4|~4.0
This package is not auto-updated.
Last update: 2024-09-10 03:10:01 UTC
README
我们非常厌倦编写/生成/更新 FormType 类,所以我们想自动化这个过程,只将更改限制在 Entity/Document/Whatever 类上,并直接获取新的表单 - 这就是 FormGenerator 的由来。
您正在查看 2.0 版本的文档
基本用法
考虑一个类
use Codete\FormGeneratorBundle\Annotations as Form; // import Symfony form types so ::class will work /** * @Form\Form( * personal = { "title", "name", "surname", "photo", "active" }, * work = { "salary" }, * admin = { "id" = { "type" = NumberType::class }, "surname" } * ) */ class Person { public $id; /** * @Form\Field(type=ChoiceType::class, choices = { "Mr." = "mr", "Ms." = "ms" }) */ public $title; /** * @Form\Field(type=TextType::class) */ public $name; /** * @Form\Field(type=TextType::class) */ public $surname; /** * @Form\Field(type=FileType::class) */ public $photo; /** * @Form\Field(type=CheckboxType::class) */ public $active; /** * @Form\Field(type=MoneyType::class) */ public $salary; }
现在我们不再需要编写整个 PersonFormType
并填充 FormBuilder,我们可以使用
use Codete\FormGeneratorBundle\FormGenerator; $generator = $this->get(FormGenerator::class); $person = new Person(); $form = $generator->createFormBuilder($person)->getForm(); $form->handleRequest($request);
哇!为我们自动生成了编辑所有注解属性的表单。我们甚至可以省略注解中的 type=".."
,如果 Symfony 能够为我们猜测字段类型。
指定字段选项
默认情况下,您在 @Form\Field
注解中指定的所有内容(除了 type
)都将作为选项传递给生成的表单类型。为了说明
/** * @Form\Field(type=ChoiceType::class, choices = { "Mr." = "mr", "Ms." = "ms" }, "attr" = { "class" = "foo" }) */ public $title;
等同于
$fb->add('title', ChoiceType::class, [ 'choices' => [ 'Mr.' => 'mr', 'Ms.' => 'ms' ], 'attr' => [ 'class' => 'foo' ], ]);
这种方法有几个优点,比如每次指定选项时都能节省很多按键,但也有缺点。首先,如果您忘记 unset
任何自定义选项,Symfony 会不高兴,并通过抛出异常来通知您。另一个缺点是我们已经保留 type
属性,并且它作为重复类型的选项是必需的。如果您遇到上述任何情况,或者您更喜欢明确指定,可以将所有 Symfony 字段选项放入 options
属性中
/** * @Form\Field( * type=ChoiceType::class, * options={ "choices" = { "Mr." = "mr", "Ms." = "ms" }, "attr" = { "class" = "foo" } } * ) */ public $title;
当表单生成器创建一个表单字段并找到 options
属性时,它将它们作为该字段的选项传递给 FormBuilder
。实际上,这允许您将字段的选项与配置修改器的选项分开,这本身可能就是一种收益。
添加未映射到属性的字段
有时您可能需要添加一个不会映射到属性的表单。这种用例的例子是向表单添加按钮
/** * The first value in Field annotation specifies field's name. * * @Form\Field("reset", type=ResetType::class) * @Form\Field("submit", type=SubmitType::class, "label"="Save") */ class Person
类级别上添加的所有字段都在生成的表单中最后,除非表单视图(下面将描述)指定了其他方式。与类级别的其他设置不同,@Field
不会被子类继承。
表单视图
在示例中,我们在 @Form\Form
注解中定义了额外的表单视图,这样我们就可以向 createFormBuilder
添加另一个参数
$form = $generator->createFormBuilder($person, 'personal')->getForm();
我们将得到具有注解中指定属性的表单。我们还可以像这样添加/覆盖字段及其属性
/** * @Form\Form( * work = { "salary" = { "attr" = { "class" = "foo" } } } * ) */ class Person
但是,如果您需要比注解更复杂的东西,我们已准备了几个可以手动添加或通过标记服务添加的可能性。对于每个可能性,FormGenerator 允许您通过可选的 $context
参数传递任何您想要传递的附加信息。两种方法都允许您指定 priority
,它定义了执行顺序(默认为 0
,如果有两个或多个服务具有相同的优先级,则首先添加的将被执行)。
如果您已启用 服务自动配置,则此 Bundle 将自动为您标记服务。
FormViewProvider
这些用于为表单提供字段列表和/或基本配置,并且与 @Form\Form
注解做完全相同的事情。
服务标记:form_generator.view_provider
表单配置修改器
这些可以修改类本身或表单视图提供者提供的任何表单配置。您可以随意删除或添加更多内容到您的表单,或调整现有的配置
服务标签:form_generator.configuration_modifier
class InactivePersonModifier implements FormConfigurationModifierInterface { public function modify($model, $configuration, $context) { unset($configuration['salary']); return $configuration; } public function supports($model, $configuration, $context) { return $model instanceof Person && $model->active === false; } }
表单字段解析器
这些负责在表单中创建实际字段,可以用于例如将转换器附加到您的字段。
服务标签:form_generator.field_resolver
class PersonSalaryResolver implements FormFieldResolverInterface { public function getFormField(FormBuilderInterface $fb, $field, $type, $options, $context) { $transformer = new /* ... */; return $fb->create($field, $type, $options) ->addViewTransformer($transformer); } public function supports($model, $field, $type, $options, $context) { return $model instanceof Person && $field === 'salary'; } }
嵌入式表单
如果您需要嵌入式表单,我们为您提供了支持
/** * @Form\Embed(class="Codete\FormGeneratorBundle\Tests\Model\Person") */ public $person;
此类子表单将包含给定模型的所有注解属性。要指定生成嵌入式表单的视图,只需在配置中指定即可
/** * @Form\Embed( * class="Codete\FormGeneratorBundle\Tests\Model\Person", * view="work" * ) */ public $employee;