codete/form-generator-bundle

Symfony 动态表单生成 Bundle

安装量: 20 179

依赖关系: 0

建议者: 0

安全性: 0

星星: 33

关注者: 8

分支: 7

开放问题: 2

类型:symfony-bundle

2.0.0 2017-12-04 16:11 UTC

This package is not auto-updated.

Last update: 2024-09-10 03:10:01 UTC


README

Build Status SensioLabsInsight

我们非常厌倦编写/生成/更新 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;