gpt4 book ai didi

symfony - symfony2链式选择器

转载 作者:行者123 更新时间:2023-12-03 11:53:06 26 4
gpt4 key购买 nike

我有三个实体:国家,州和城市,具有以下关系:
Image

创建城市时,我需要两个选择器,一个用于城市,一个用于城市所属的州。这两个选择器需要链接在一起,因此更改“国家”将“过滤”另一个选择器中显示的国家。
我发现了一个tutorial,它显示了如何使用表单事件来执行此操作,但是他们的示例并不是我的情况。我的实体城市与国家(地区)实体没有直接关系(它们通过州(State)间接关联),因此,当在城市(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()”
有任何想法吗?

最佳答案

好的,我终于想出了正确的做法:

namespace Test\TestBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\Event\DataEvent;

use Test\TestBundle\Entity\Country;
use Test\TestBundle\Entity\State;
use Test\TestBundle\Entity\City;


class CityType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$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',
'empty_value' => '-- Select a state --',
'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', null);
}

return $qb;
})
));
};

$setCountry = function ($form, $country) use ($factory) {
$form->add($factory->createNamed('entity', 'country', null, array(
'class' => 'TestBundle:Country',
'property' => 'name',
'property_path' => false,
'empty_value' => '-- Select a country --',
'data' => $country,
)));
};

$builder->addEventListener(FormEvents::PRE_SET_DATA, function (DataEvent $event) use ($refreshStates, $setCountry) {
$form = $event->getForm();
$data = $event->getData();

if ($data == null) {
return;
}

if ($data instanceof City) {
$country = ($data->getId()) ? $data->getState()->getCountry() : null ;
$refreshStates($form, $country);
$setCountry($form, $country);
}
});

$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');
}
}

jQuery AJAX选择器

$(document).ready(function () {
$('#city_country').change(function(){
$('#city_state option:gt(0)').remove();
if($(this).val()){
$.ajax({
type: "GET",
data: "country_id=" + $(this).val(),
url: Routing.generate('state_list'),
success: function(data){
$('#city_state').append(data);
}
});
}
});
});

我希望这将对面临相同情况的其他人有所帮助。

关于symfony - symfony2链式选择器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10186185/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com