Ho tre entità: Paese, stato e la città con le seguenti relazioni:Symfony2 incatenato selettori
Image http://i39.tinypic.com/15gc85u.png
Durante la creazione di una Città, voglio due selettori, uno per il Paese e una per lo stato in cui la città appartiene Questi due selettori devono essere concatenati in modo che la modifica del Paese "filtri" gli Stati mostrati nell'altro selettore.
Ho trovato un tutorial che mostra come farlo utilizzando Form Events ma il loro esempio non è proprio il mio caso. La mia entità Città non è direttamente correlata all'entità Paese (sono indirettamente correlati tramite Stato) quindi, quando si imposta il campo Paese nel modulo Città (all'interno della classe CityType), sono costretto a dichiarare tale campo come 'property_path'=>false
come è possibile vedere nel seguente codice:
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');
}
}
il problema è che quando si tenta di modificare una città esistente, il relativo Paese non è selezionata per impostazione predefinita nella forma. Se rimuovo la linea 'property_path'=>false
ottengo (non sorprendentemente) il messaggio di errore:
Né proprietà "paese", né il metodo "getCountry()" o il metodo "isCountry()" esiste in classe "Test \ TestBundle \ Entity \ Città "
Qualche idea?
da dove proviene il 'Routing.generate ('state_list'),' '? dove si trova il controller che gestisce la route 'state_list'? – gondo
Ciao David, ottima risposta, mi chiedo solo: hai qualche idea di come utilizzare questa città creata quando selezioni, ad esempio, un indirizzo per una persona? Quindi selezionare un paese, che aggiorna gli stati, selezionare uno stato, che aggiorna le città? So che ha qualcosa a che fare con i Form Events, ma mi sembra che tu debba annidarli in qualche modo? Ho postato una domanda su questo [qui] (http://stackoverflow.com/questions/20544442/add-event-listener-to-form-element-added-by-event-listener). Qualche idea? – iLikeBreakfast
come farlo nella versione 'Symfony 2.3' –