我正在使用 Symfony 6.4,我不确定如何分解表单中的代码。
这是一个具体的例子:
在 UserRegistrationType 中,我这样做:
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('email', TextType::class, [
'label' => 'Email',
'attr' => [
'placeholder' => 'Email'
],
])
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'Les mots de passe ne correspondent pas.',
'options' => [
'attr' => [
'autocomplete' => 'new-password',
],
],
'required' => true,
'first_options' =>
[
'label' => 'Mot de passe',
'attr' =>
[
'placeholder' => 'Mot de passe',
'class' => 'verify-password'
]
],
'second_options' => ['label' => 'Répéter le mot de passe', 'attr' => ['placeholder' => 'Répéter le mot de passe']],
])
->add('nom', TextType::class, [
'label' => 'Nom',
'attr' => [
'placeholder' => 'Nom',
],
])
->add('prenom', TextType::class, [
'label' => 'Prénom',
'attr' => [
'placeholder' => 'Prénom',
],
])
}
在网站的某一部分,我只需要能够修改用户的密码。不是电子邮件,不是姓名,不是名字,只是密码。
所以,我使用 UserPasswordType:
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'Les mots de passe ne correspondent pas.',
'options' => [
'attr' => [
'autocomplete' => 'new-password',
],
],
'required' => true,
'first_options' =>
[
'label' => 'Mot de passe',
'attr' =>
[
'placeholder' => 'Mot de passe',
'class' => 'verify-password'
]
],
'second_options' => ['label' => 'Répéter le mot de passe', 'attr' => ['placeholder' => 'Répéter le mot de passe']],
]);
}
但我可以看到我复制并粘贴了相同的逻辑两次。
有没有一种解决方案可以只编写一次逻辑并在我需要的每个 FormType 中使用它?
是的,你可以。有几种方法可以做到这一点。选择适合您的。
方法1.创建自己的表单类型并配置默认值。
https://symfony.com/doc/current/form/create_custom_field_type.html
class MyRepeatedPasswordType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'type' => PasswordType::class,
'invalid_message' => 'Les mots de passe ne correspondent pas.',
'options' => [
'attr' => [
'autocomplete' => 'new-password',
],
],
'required' => true,
'first_options' =>
[
'label' => 'Mot de passe',
'attr' =>
[
'placeholder' => 'Mot de passe',
'class' => 'verify-password'
]
],
'second_options' => ['label' => 'Répéter le mot de passe', 'attr' => ['placeholder' => 'Répéter le mot de passe']],
]);
}
public function getParent(): string
{
return RepeatedType::class;
}
}
您可以按如下方式将其添加到您的表格中:
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('password', MyRepeatedPasswordType::class);
}
方法二:工厂模式
这可能是最简单的方法,但可能不是优选的。
您可以创建一个工厂类,您可以调用该工厂类来删除重复代码。
class MyFormBuilderFactory
{
public static function passwordField(FormBuilderInterface $builder): void
{
$builder
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'Les mots de passe ne correspondent pas.',
'options' => [
'attr' => [
'autocomplete' => 'new-password',
],
],
'required' => true,
'first_options' =>
[
'label' => 'Mot de passe',
'attr' =>
[
'placeholder' => 'Mot de passe',
'class' => 'verify-password'
]
],
'second_options' => ['label' => 'Répéter le mot de passe', 'attr' => ['placeholder' => 'Répéter le mot de passe']],
]);
}
}
然后您可以在表单中使用工厂。
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('email', TextType::class);
MyFormBuilderFactory::passwordField($builder);
$builder
->add('other_field', ...);
}
可能还有更多方法,但我遇到过这些。