2013-12-12 8 views
9

द्वारा जोड़े गए तत्व बनाने के लिए ईवेंट श्रोता जोड़ें, मैं एक सिम्फनी ऐप बना रहा हूं और पूरे "राज्य/इलाके" चीज़ को करने के लिए कुछ jquery/AJAX के साथ फॉर्म इवेंट्स का उपयोग कर रहा हूं। हालांकि मुझे थोड़ा सा मुद्दा है, मैं प्रारूप प्रांत -> शहर -> उपनगर का उपयोग कर रहा हूं। जाहिर हैइवेंट श्रोता

The child with the name "physicalCity" does not exist.

यह: अब जहाँ तक मैं बता सकता हूँ मेरे कोड ठीक है, लेकिन जब निष्पादन अनुभाग जहां मैं "शहर" के लिए एक श्रोता जोड़ने के हिट का चयन, यह निम्न कह एक त्रुटि फेंकता तब होता है जब मैं नए बनाए गए फ़ील्ड में इवेंट श्रोता को आज़माता हूं और जोड़ता हूं, इस प्रकार किसी ईवेंट श्रोता द्वारा बनाए गए तत्व में इवेंट श्रोता जोड़ता है?

कोड का एक अनुभाग नीचे है ... मैं क्या गलत कर रहा हूं? किसी भी मदद को बहुत, बहुत सराहा जाएगा!

public function buildForm(FormBuilderInterface $builder, array $options) { 
     $builder 
      ->add('schoolName') 
      ->add('physicalProvince', 'entity', array(
       'mapped' => false, 
       'class' => 'MY\MainBundle\Entity\Province', 
       'empty_value' => 'Select a province', 
       'attr' => array(
        'class' => 'province', 
        'data-show' => 'physical-city', 
       ) 
      )); 

     /* 
     * For the physical cities 
     */ 
     $physicalCityModifier = function(FormInterface $form, Province $province = null) { 
      if (null !== $province) 
       $cities = $province->getCities(); 
      else 
       $cities = array(); 

      $form->add('physicalCity', 'entity', array(
       'mapped' => false, 
       'class' => 'MY\MainBundle\Entity\City', 
       'empty_value' => 'Select a province first', 
       'choices' => $cities, 
       'attr' => array(
        'class' => 'city physical-city', 
        'data-show' => 'physical-suburb' 
       ) 
      )); 
     }; 

     $builder->addEventListener(
      FormEvents::PRE_SET_DATA, 
      function(FormEvent $event) use ($physicalCityModifier) { 
       $data = $event->getData(); 
       if (is_object($data->getPhysicalSuburb())) 
        $province = $data->getPhysicalSuburb()->getCity()->getProvince(); 
       else 
        $province = null; 

       $physicalCityModifier($event->getForm(), $province); 
      } 
     ); 

     $builder->get('physicalProvince')->addEventListener(
      FormEvents::POST_SUBMIT, 
      function (FormEvent $event) use ($physicalCityModifier) { 
       $province = $event->getForm()->getData(); 
       $physicalCityModifier($event->getForm()->getParent(), $province); 
      } 
     ); 

     /* 
     * For the physical suburbs 
     */ 
     $physicalSuburbModifier = function(FormInterface $form, City $city = null) { 
      if (null !== $city) 
       $suburbs = $city->getSuburbs(); 
      else 
       $suburbs = array(); 

      $form->add('physicalSuburb', null, array(
       'choices' => $suburbs, 
       'empty_value' => 'Select a city first', 
       'attr' => array(
        'class' => 'physical-suburb' 
       ), 
      )); 
     }; 

     $builder->addEventListener(
      FormEvents::PRE_SET_DATA, 
      function(FormEvent $event) use ($physicalSuburbModifier) { 
       $data = $event->getData(); 
       if (is_object($data->getCity())) 
        $city = $data->getCity(); 
       else 
        $city = null; 

       $physicalSuburbModifier($event->getForm(), $city); 
      } 
     ); 

     $builder->get('physicalCity')->addEventListener(
      FormEvents::POST_SUBMIT, 
      function(FormEvent $event) use ($physicalSuburbModifier) { 
       $city = $event->getForm()->getData(); 

       $physicalSuburbModifier($event->getForm()->getParent(), $city); 
      } 
     ); 
} 

उत्तर

14

किसी और ने वही समस्या है, तो मैं अंत में यह सही प्रत्येक क्षेत्र के लिए घटना ग्राहकों के साथ मिला है, this site से मदद (हमारे बीच उन गैर स्पेनिश बोलने लोक के लिए इसका अनुवाद) के साथ।

मूल रूप से, मैंने जो किया वह प्रांत सहित प्रत्येक क्षेत्र के लिए एक नया सब्सक्राइबर वर्ग बना रहा था, और उसके बाद उन्होंने प्रत्येक के अंदर एक प्रश्न निर्माता बनाया जो पिछले क्षेत्रों के उन लोगों के साथ अपने मूल्यों को तैयार करने के लिए बनाया गया था। कोड नीचे दिखाया गया है।

AddProvinceFieldSubscriber.php

class AddProvinceFieldSubscriber implements EventSubscriberInterface { 
    private $factory; 
    private $fieldName; 
    private $type; 

    public function __construct(FormFactoryInterface $factory, $fieldName) { 
     $this->factory = $factory; 
     $this->fieldName = $fieldName . 'Province'; 
     $this->type = $fieldName; 
    } 

    public static function getSubscribedEvents() { 
     return array(
      FormEvents::PRE_SET_DATA => 'preSetData', 
      FormEvents::PRE_SUBMIT => 'preSubmit', 
     ); 
    } 

    private function addProvinceForm(FormInterface $form, $province) { 
     $form->add($this->factory->createNamed($this->fieldName, 'entity', $province, array(
      'class' => 'MyThing\MainBundle\Entity\Province', 
      'mapped' => false, 
      'empty_value' => 'Select a province', 
      'query_builder' => function (EntityRepository $repository) { 
       $qb = $repository->createQueryBuilder('p'); 
       return $qb; 
      }, 
      'auto_initialize' => false, 
      'attr' => array(
       'class' => 'province ' . $this->type .'-province', 
       'data-show' => $this->type . '-city', 
      ) 
     ))); 
    } 

    public function preSetData(FormEvent $event) { 
     $form = $event->getForm(); 
     $data = $event->getData(); 

     if (null === $data) 
      return; 

     $fieldName = 'get' . ucwords($this->type) . 'Suburb'; 
     $province = ($data->$fieldName()) ? $data->$fieldName()->getCity()->getProvince() : null; 
     $this->addProvinceForm($form, $province); 
    } 

    public function preSubmit(FormEvent $event) { 
     $form = $event->getForm(); 
     $data = $event->getData(); 

     if (null === $data) 
      return; 

     $province = array_key_exists($this->fieldName, $data) ? $data[$this->fieldName] : null; 
     $this->addProvinceForm($form, $province); 
    } 
} 

AddCityFieldSubscriber.php

class AddCityFieldSubscriber implements EventSubscriberInterface { 
    private $factory; 
    private $fieldName; 
    private $provinceName; 
    private $suburbName; 
    private $type; 

    public function __construct(FormFactoryInterface $factory, $fieldName) { 
     $this->factory = $factory; 
     $this->fieldName = $fieldName . 'City'; 
     $this->provinceName = $fieldName . 'Province'; 
     $this->suburbName = $fieldName . 'Suburb'; 
     $this->type = $fieldName; 
    } 

    public static function getSubscribedEvents() { 
     return array(
      FormEvents::PRE_SET_DATA => 'preSetData', 
      FormEvents::PRE_SUBMIT => 'preSubmit', 
     ); 
    } 

    private function addCityForm(FormInterface $form, $city, $province) { 
     $form->add($this->factory->createNamed($this->fieldName, 'entity', $city, array(
      'class' => 'MyThing\MainBundle\Entity\City', 
      'empty_value' => 'Select a city', 
      'mapped' => false, 
      'query_builder' => function (EntityRepository $repository) use ($province) { 
       $qb = $repository->createQueryBuilder('c') 
           ->innerJoin('c.province', 'province'); 
       if ($province instanceof Province) { 
        $qb->where('c.province = :province') 
         ->setParameter('province', $province); 
       } elseif (is_numeric($province)) { 
        $qb->where('province.id = :province') 
         ->setParameter('province', $province); 
       } else { 
        $qb->where('province.provinceName = :province') 
         ->setParameter('province', null); 
       } 

       return $qb; 
      }, 
      'auto_initialize' => false, 
      'attr' => array(
       'class' => 'city ' . $this->type . '-city', 
       'data-show' => $this->type . '-suburb', 
      ) 
     ))); 
    } 

    public function preSetData(FormEvent $event) { 
     $data = $event->getData(); 
     $form = $event->getForm(); 

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

     $fieldName = 'get' . ucwords($this->suburbName); 
     $city = ($data->$fieldName()) ? $data->$fieldName()->getCity() : null; 
     $province = ($city) ? $city->getProvince() : null; 
     $this->addCityForm($form, $city, $province); 
    } 

    public function preSubmit(FormEvent $event) { 
     $data = $event->getData(); 
     $form = $event->getForm(); 

     if (null === $data) 
      return; 

     $city = array_key_exists($this->fieldName, $data) ? $data[$this->fieldName] : null; 
     $province = array_key_exists($this->provinceName, $data) ? $data[$this->provinceName] : null; 
     $this->addCityForm($form, $city, $province); 
    } 
} 

और अंत में AddSuburbFieldSubscriber.php

class AddSuburbFieldSubscriber implements EventSubscriberInterface { 
    private $factory; 
    private $fieldName; 
    private $type; 

    public function __construct(FormFactoryInterface $factory, $fieldName) { 
     $this->factory = $factory; 
     $this->fieldName = $fieldName . 'Suburb'; 
     $this->type = $fieldName; 
    } 

    public static function getSubscribedEvents() { 
     return array(
      FormEvents::PRE_SET_DATA => 'preSetData', 
      FormEvents::PRE_SUBMIT => 'preSubmit', 
     ); 
    } 

    private function addSuburbForm(FormInterface $form, $city) { 
     $form->add($this->factory->createNamed($this->fieldName, 'entity', null, array(
      'class' => 'MyThing\MainBundle\Entity\Suburb', 
      'empty_value' => 'Select a suburb', 
      'query_builder' => function (EntityRepository $repository) use ($city) { 
       $qb = $repository->createQueryBuilder('s') 
           ->innerJoin('s.city', 'city'); 

       if ($city instanceof City) { 
        $qb->where('s.city = :city') 
         ->setParameter('city', $city); 
       } elseif (is_numeric($city)) { 
        $qb->where('city.id = :city') 
         ->setParameter('city', $city); 
       } else { 
        $qb->where('city.cityName = :city') 
         ->setParameter('city', null); 
       } 
        $sql = $qb->getQuery()->getSQL(); 

       return $qb; 
      }, 
      'auto_initialize' => false, 
      'attr' => array(
       'class' => 'suburb ' . $this->type . '-suburb', 
      ), 
     ))); 
    } 

    public function preSetData(FormEvent $event) { 
     $data = $event->getData(); 
     $form = $event->getForm(); 

     if (null === $data) 
      return; 

     $fieldName = 'get' . ucwords($this->fieldName); 
     $city = ($data->$fieldName()) ? $data->$fieldName()->getCity() : null; 
     $this->addSuburbForm($form, $city); 
    } 

    public function preSubmit(FormEvent $event) { 
     $data = $event->getData(); 
     $form = $event->getForm(); 

     if (null === $data) 
      return; 

     $city = array_key_exists($this->type . 'City', $data) ? $data[$this->type . 'City'] : null; 
     $this->addSuburbForm($form, $city); 
    } 
} 

मैं वहाँ में कुछ अतिरिक्त सामान को जोड़ने के लिए किया था, लेकिन आपको मिल इसका सारांश

$builder 
    ->addEventSubscriber(new AddProvinceFieldSubscriber($factory, 'postal')) 
    ->addEventSubscriber(new AddCityFieldSubscriber($factory, 'postal')) 
    ->addEventSubscriber(new AddSuburbFieldSubscriber($factory, 'postal')) 
//... 

और खुश दिन:

मेरी प्रपत्र प्रकार में मैं बस निम्नलिखित जोड़ा गया! उम्मीद है कि यह किसी की मदद करता है।

इसके अलावा, मैंने data-show विशेषताओं को मेरी AJAX प्रक्रिया को सरल बनाने के लिए जोड़ा, बस अगर कोई सोच रहा था।

+2

शानदार काम! आपने मेरा दिन बचाया, धन्यवाद! :) – Gianluca78

+0

क्या यह इस सामग्री को संपादित करते समय भी काम करता है। मेरे लिए यह नहीं था। क्या आप कृपया उत्तर दे सकते हैं कि सिम्फनी के किस संस्करण ने आप इसे काम किया था? – Jeet

+0

हाँ यह मेरे लिए काम किया। यह एसएफ 2.4 था मेरा मानना ​​है, बिल्कुल याद नहीं कर सकता। क्वेरी बिल्डर निर्णय के मामलों के साथ बस कोशिश करें और खेलो। शायद आपके मामले में कुछ अजीब है। और XDebug स्थापित करें! बहुत मदद करता है। – iLikeBreakfast

संबंधित मुद्दे