2015-01-12 9 views
5

Mam niestandardowy typ FormType, który musi dodać się do jednostki nadrzędnej, gdy formularz nadrzędny będzie się utrzymywał.Symfony2 (> = 2.3): Jak odsłuchać wydarzenie w formie rodzica od dziecka?

< W Symfony 2.3 można to zrobić w następujący sposób:

class FooType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     parent::buildForm($builder, $options); 
     ... 
     $builder->getParent()->addEventSubscriber(new FooSubscriber) 
    } 
} 

class FooSubscriber implements EventSubscriberInterface 
{ 
    static function getSubscribedEvents() 
    { 
     return array(
      FormEvents::POST_SUBMIT => 'postSubmit' 
     ); 
    } 
} 

Ale po uaktualnieniu do Symfony 2.6 Odkryłam, że $builder->getParent() został usunięty. Ale teraz nie mogę słuchać nadsyłanego rodzica.

Więc dodałem detektor do mojego konstruktora i odwołałem się do rodzica z subskrybenta. Ale to naprawdę nie działa, ponieważ robię czek na formularzu dominującej jest ważne - co nie jest, ponieważ nie jest jeszcze składać:

function postSubmit(FormEvent $e) 
{ 
    if ($e->getForm()->getParent()->getRoot()->isValid()) { 
     //this gives 'false' 

Ta fałszywa jest spowodowane przez następny kawałek kodu:

// Symfony\Component\Form\Form.php @ line 744 
public function isValid() 
{ 
    if (!$this->submitted) { 
     return false; 
    } 

a ponieważ forma dominująca pierwszy pętli przez wszystkie dzieciaki i twierdzi, że przed ustawieniem $this->submitted = true na siebie ... nie jestem pewien, czy rodzic jest ważny.


TL; DR

Jak mogę dodać EventListener do mojego formularza nadrzędnego, bez konieczności dostosowania moja forma rodzicem? Chcę, aby mój FooType był czymś, co mogę dodać do wszystkich formularzy, bez konieczności znajomości/pamiętania, aby zrobić jakąś logikę dla tego specyficznego FooType.

+0

Jak powiedziałeś, getParent został usunięty w wersji 2.3. Czy możesz opisać przypadek użycia bardziej szczegółowo? Może być lepszym rozwiązaniem. – Cerad

+1

Jest to jednostka, którą można dodać do innej jednostki. W tym przypadku jest to MenuItem, który jest tworzony po utrwaleniu strony. Ta pozycja menu jest oparta na tytule strony, więc do wejścia potrzebny jest jej element nadrzędny. Ale nie chcę aby strona wiedziała, że ​​istnieje MenuItem, które zależy od niego. Więc wcześniej, po prostu mogłem dodać MenuItem do PageAdmin i to było to. Teraz mogę_ dodać subskrybenta w administratorze - co jest ** brudne ** – Oskar

+0

Mając ten sam problem, chcę wiedzieć, czy formularz główny jest prawidłowy, nie mogę znaleźć sposobu, aby to zrobić w 2.6 :( – Tiois

Odpowiedz

0

Potrzebowałem tej samej funkcjonalności, ponieważ mam niestandardowe pole formularza, które potrzebuje jednostki nadrzędnej po zaktualizowaniu wszystkich mapowanych pól. Niestety POST_SUBMIT formularzy podrzędnych jest wywoływany przed wysłaniem polecenia SUBMIT do rodzica.

Skończyło się na przekazaniu eventDispatcher do dziecka i przywiązywaniu tam mojego słuchacza. Potrzebowałem dwóch słuchaczy, aby wykonać zadanie: jeden, aby uzyskać przetworzoną wartość, a drugi, aby zaktualizować główną jednostkę. przekazywanie $ generatedPassword do zamknięcia przez odniesienie pozwala na udostępnianie danych ze zdarzenia potomnego rodzicowi.

Parent :: buildForm

$builder->add('generate_password', GeneratePasswordType::class, [ 
    'event_dispatcher' => $builder->getEventDispatcher(), 
]); 

Child :: buildForm

//first listed to submit even to get current field value 
$generateNewPassword = false; 
$builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) use (&generateNewPassword) { 
    $generateNewPassword = null !== $event->getData(); 
}); 

//then run updater after parent entity has been updated 
$parentDispatcher = $options['event_dispatcher']; 
$parentDispatcher->addListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use (&$generateNewPassword) { 
    $user = $event->getData(); 
    if(true === $generateNewPassword){ 
     //update password & email user new credentials 
    } 
} 

(Pole zwyczaj jest zaznaczone pole wyboru 'wygenerować nowe hasło przy zapisywaniu' dla modułu zarządzania użytkownikami. It te e-maile użytkownik wygenerował hasło, dlatego potrzebuję najnowszego adresu e-mail od głównego podmiotu)

+0

To jest pomysł, ale nadal wymaga modyfikacji formularza nadrzędnego i podobnie jak PO nie mogę go zmodyfikować. –