如何使用 “inherit_data” 减少代码重复
当你在不同的实体中有一些重复字段时,inherit_data
表单字段选项非常有用。 例如,假设你有两个实体,一个 Company
和一个 Customer
1 2 3 4 5 6 7 8 9 10 11 12 13
// src/Entity/Company.php
namespace App\Entity;
class Company
{
private string $name;
private string $website;
private string $address;
private string $zipcode;
private string $city;
private string $country;
}
1 2 3 4 5 6 7 8 9 10 11 12 13
// src/Entity/Customer.php
namespace App\Entity;
class Customer
{
private string $firstName;
private string $lastName;
private string $address;
private string $zipcode;
private string $city;
private string $country;
}
正如你所看到的,每个实体都共享一些相同的字段:address
、zipcode
、city
、country
。
首先为这些实体构建两个表单,CompanyType
和 CustomerType
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// src/Form/Type/CompanyType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class CompanyType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('name', TextType::class)
->add('website', TextType::class);
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// src/Form/Type/CustomerType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class CustomerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('firstName', TextType::class)
->add('lastName', TextType::class);
}
}
与其在这两个表单中都包含重复的字段 address
、zipcode
、city
和 country
,不如为此创建一个名为 LocationType
的第三个表单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
// src/Form/Type/LocationType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class LocationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('address', TextareaType::class)
->add('zipcode', TextType::class)
->add('city', TextType::class)
->add('country', TextType::class);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'inherit_data' => true,
]);
}
}
位置表单有一个有趣的选项设置,即 inherit_data
。 此选项允许表单从其父表单继承数据。 如果嵌入到公司表单中,位置表单的字段将访问 Company
实例的属性。 如果嵌入到客户表单中,这些字段将访问 Customer
实例的属性。 很方便,对吧?
注意
除了在 LocationType
内部设置 inherit_data
选项之外,你也可以(就像任何选项一样)在 $builder->add()
的第三个参数中传递它。
最后,通过将位置表单添加到你的两个原始表单中来使其工作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// src/Form/Type/CompanyType.php
namespace App\Form\Type;
use App\Entity\Company;
use Symfony\Component\Form\AbstractType;
// ...
class CompanyType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
// ...
$builder->add('foo', LocationType::class, [
'data_class' => Company::class,
]);
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// src/Form/Type/CustomerType.php
namespace App\Form\Type;
use App\Entity\Customer;
use Symfony\Component\Form\AbstractType;
class CustomerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
// ...
$builder->add('bar', LocationType::class, [
'data_class' => Customer::class,
]);
}
}
就是这样! 你已经将重复的字段定义提取到一个单独的位置表单中,你可以在任何需要它的地方重用它。
警告
设置了 inherit_data
选项的表单不能有 *_SET_DATA
事件监听器。
这项工作,包括代码示例,根据 Creative Commons BY-SA 3.0 许可协议获得许可。