我有三个实体:国家、州和城市,具有以下关系:
创建城市时,我需要两个选择器,一个用于国家,一个用于城市所属的州。这两个选择器需要链接,因此更改国家将“过滤”另一个选择器中显示的状态。
我找到了一个教程,展示了如何使用表单事件来做到这一点,但他们的例子并不是我的情况。我的实体 City 它与 Country 实体没有直接关系(它们通过 State 间接相关)所以,当在 City 表单中设置 country 字段时(在 CityType 类中),我被迫声明该字段,'property_path'=>false
如您所见在下面的代码中:
class CityType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('country', 'entity', array(
'class'=>'TestBundle:Country',
'property'=>'name',
'property_path'=>false //Country is not directly related to City
));
$builder->add('name');
$factory = $builder->getFormFactory();
$refreshStates = function ($form, $country) use ($factory)
{
$form->add($factory->createNamed('entity', 'state', null, array(
'class' => 'Test\TestBundle\Entity\State',
'property' => 'name',
'query_builder' => function (EntityRepository $repository) use ($country)
{
$qb = $repository->createQueryBuilder('state')
->innerJoin('state.country', 'country');
if($country instanceof Country) {
$qb->where('state.country = :country')
->setParameter('country', $country);
} elseif(is_numeric($country)) {
$qb->where('country.id = :country')
->setParameter('country', $country);
} else {
$qb->where('country.name = :country')
->setParameter('country', "Venezuela");;
}
return $qb;
}
)));
};
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (DataEvent $event) use ($refreshStates)
{
$form = $event->getForm();
$data = $event->getData();
if($data == null)
return;
if($data instanceof City){
if($data->getId()) { //An existing City
$refreshStates($form, $data->getState()->getCountry());
}else{ //A new City
$refreshStates($form, null);
}
}
});
$builder->addEventListener(FormEvents::PRE_BIND, function (DataEvent $event) use ($refreshStates)
{
$form = $event->getForm();
$data = $event->getData();
if(array_key_exists('country', $data)) {
$refreshStates($form, $data['country']);
}
});
}
public function getName()
{
return 'city';
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'Test\TestBundle\Entity\City');
}
}
问题是当我尝试编辑现有城市时,默认情况下不会在表单中选择相关的国家。如果我删除该行'property_path'=>false
,我会(毫不奇怪)收到错误消息:
“Test\TestBundle\Entity\City”类中不存在属性“country”、方法“getCountry()”和方法“isCountry()”
有任何想法吗?