- 原文出處:http://symfony.com/doc/2.1/cookbook/form/use_virtuals_forms.html
- 原文作者:symfony.com
- 授權許可:創作共用協議
- 翻譯人員:FireHare
- 校對人員:FireHare
- 適用版本:Symfony 2.1
- 文章狀態:草譯階段
The virtual
form field option can be very useful when you have some duplicated fields in different entities.
當您在不同的實體中擁有一些重複的表單域時,虛擬表單域選項就顯得非常有用。
For example, imagine you have two entities, a Company
and a Customer
:
舉個例子,想象您有兩個實體,Company和Customer:
Company實體:
- // src/Acme/HelloBundle/Entity/Company.php
- namespace Acme\HelloBundle\Entity;
-
- class Company
- {
- private $name;
- private $website;
-
- private $address;
- private $zipcode;
- private $city;
- private $country;
- }
Customer實體:
- // src/Acme/HelloBundle/Entity/Customer.php
- namespace Acme\HelloBundle\Entity;
-
- class Customer
- {
- private $firstName;
- private $lastName;
-
- private $address;
- private $zipcode;
- private $city;
- private $country;
- }
Like you can see, each entity shares a few of the same fields: address
, zipcode
, city
, country
.
正如您所見,每個實體都有著一些相同的表單域:address、zipcode、city和country。
Now, you want to build two forms: one for a Company
and the second for a Customer
.
現在,您要建立兩個表單:一個對應Company,第二個對應Customer。
Start by creating a very simple CompanyType
and CustomerType
:
首先建立一個非常簡單的CompanyType和CustomerType:
CompanyType類:
- // src/Acme/HelloBundle/Form/Type/CompanyType.php
- namespace Acme\HelloBundle\Form\Type;
-
- use Symfony\Component\Form\FormBuilderInterface;
-
- class CompanyType extends AbstractType
- {
- public function buildForm(FormBuilderInterface $builder, array $options)
- {
- $builder
- ->add('name', 'text')
- ->add('website', 'text');
- }
- }
CustomerType類:
- // src/Acme/HelloBundle/Form/Type/CustomerType.php
- namespace Acme\HelloBundle\Form\Type;
-
- use Symfony\Component\Form\FormBuilderInterface;
-
- class CustomerType extends AbstractType
- {
- public function buildForm(FormBuilderInterface $builder, array $options)
- {
- $builder
- ->add('firstName', 'text')
- ->add('lastName', 'text');
- }
- }
Now, we have to deal with the four duplicated fields. Here is a (simple) location form type:
現在我們需要處理那四個重複的表單域。下面是個簡單)的位置表單類型:
- // src/Acme/HelloBundle/Form/Type/LocationType.php
- namespace Acme\HelloBundle\Form\Type;
-
- use Symfony\Component\Form\FormBuilderInterface;
- use Symfony\Component\OptionsResolver\OptionsResolverInterface;
-
- class LocationType extends AbstractType
- {
- public function buildForm(FormBuilderInterface $builder, array $options)
- {
- $builder
- ->add('address', 'textarea')
- ->add('zipcode', 'text')
- ->add('city', 'text')
- ->add('country', 'text');
- }
-
- public function setDefaultOptions(OptionsResolverInterface $resolver)
- {
- $resolver->setDefaults(array(
- 'virtual' => true
- ));
- }
-
- public function getName()
- {
- return 'location';
- }
- }
We don't actually have a location field in each of our entities, so we can't directly link our LocationType
to our CompanyType
or CustomerType
. But we absolutely want to have a dedicated form type to deal with location (remember, DRY!).
實際上在每個實體中我們並沒有location表單域,因此我們不能直接將LocationType鏈入我們的CompanyType或CustomerType中。但我們又絕對想要一個專門處理位置的表單類型記住,DRY!)
The virtual
form field option is the solution.
解決這個問題就需要用到虛擬表單域選項了。
We can set the option 'virtual' => true
in the setDefaultOptions()
method of LocationType
and directly start using it in the two original form types.
我們可以在LocationType類中的
setDefaultOptions()方法中將
選項'virtual'設定為true,並且在兩個原始域類型中直接使用它。
Look at the result:
所下所示:
CompanyType類:
- // CompanyType
- public function buildForm(FormBuilderInterface $builder, array $options)
- {
- $builder->add('foo', new LocationType(), array(
- 'data_class' => 'Acme\HelloBundle\Entity\Company'
- ));
- }
CustomerType類:
- // CustomerType
- public function buildForm(FormBuilderInterface $builder, array $options)
- {
- $builder->add('bar', new LocationType(), array(
- 'data_class' => 'Acme\HelloBundle\Entity\Customer'
- ));
- }
With the virtual option set to false (default behavior), the Form Component expects each underlying object to have a foo
(or bar
) property that is either some object or array which contains the four location fields. Of course, we don't have this object/array in our entities and we don't want it!
當virtual選項設為false時預設值),表單組件期望每個相關的對象都有一個foo或bar)屬性,要麼是一些對象,要麼是包含四個位置表單域的數組。當然,在我們的實體中沒有這樣的對象或數組,而且我們也不想那樣做!
With the virtual option set to true, the Form component skips the foo
(or bar
) property, and instead "gets" and "sets" the 4 location fields directly on the underlying object!
當virtual選項設為true時,表單組件忽略foo或bar)屬性,取而代之的是在相關對象中直接"gets"和"sets"這4個位置表單域!
Instead of setting the virtual option inside LocationType , you can (just like with any options) also pass it in as an array option to the third argument of $builder->add() . 如果不使用在LocationType中設定virtual選項,您也可以如其它選項那樣)將其作為一個數組選項發送到$builder->add()的第三個參數。 |