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
class Customer
private $firstName;
private $lastName;
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
class CustomerType extends AbstractType
->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
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class LocationType extends AbstractType
->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
public function buildForm(FormBuilderInterface $builder, array $options)
$builder->add('foo', new LocationType(), array(
'data_class' => 'Acme\HelloBundle\Entity\Company'
));
// CustomerType
$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()的第三個參數。
本文轉自 firehare 51CTO部落格,原文連結:http://blog.51cto.com/firehare/1004587,如需轉載請自行聯系原作者