2015-01-12 8 views
5

Ich habe einen benutzerdefinierten FormType, der sich zur übergeordneten Entität hinzufügen muss, wenn das übergeordnete Formular bestehen bleibt.Symfony2 (> = 2.3): Wie höre ich das Elternformular vom Kind an?

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

Aber nach dem Upgrade auf Symfony 2.6 habe ich entdeckt, dass $builder->getParent() entfernt wurde:

In Symfony < 2.3 könnte dies, indem Sie folgende erfolgen. Aber jetzt kann ich nicht hören, dass der Elternteil eingereicht wird.

So habe ich den Hörer auf meine Baumeister und verwiesen die Eltern aus dem Abonnenten. Aber das funktioniert nicht wirklich, da ich einen Scheck auf das übergeordnete Formular tun gültig zu sein - was es nicht ist, da es noch nicht vorgelegt hat:

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

Diese falsche durch das nächste Stück Code verursacht wird:

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

und weil die Mutterform zuerst alle childs Schleifen durch und macht geltend, dass vor $this->submitted = true auf Einstellung selbst ... ich bin nicht sicher, ob die Eltern gültig ist.


TL; DR

Wie kann ich ein Eventlistener meiner Eltern Formular hinzufügen, ohne meine Eltern Formular anpassen zu müssen? Ich möchte, dass mein FooType etwas ist, das ich allen Formen hinzufügen kann, ohne dass ich eine Logik für diesen FooType-spezifischen Code machen muss.

+0

Wie Sie sagen, wurde getParent in 2.3 entfernt. Kannst du den Anwendungsfall genauer beschreiben? Könnte eine bessere Lösung sein. – Cerad

+1

Es ist eine Entität, die einer anderen Entität hinzugefügt werden kann. In diesem Fall ist es ein MenuItem, das erstellt wird, wenn eine Seite persistent ist. Das MenuItem wird auf dem Titel der Seite basiert, so dass dafür ist es, es ist Eltern für die Eingabe benötigt. Aber ich möchte nicht, dass die Seite weiß, dass es ein MenuItem gibt, das von ihm abhängt. Also vorher konnte ich dem PageAdmin ein MenuItem hinzufügen und das war es. Jetzt _have ich einen Teilnehmer im Admin to_ hinzufügen - die ** ** schmutzig – Oskar

+0

mit dem gleichen Problem fühlt, ich möchte wissen, ob die Wurzel Form gültig ist, kann ich nicht einen Weg, es zu tun in 2 finden.Die 6 :( – Tiois

Antwort

0

brauchte ich die gleiche Funktionalität, weil ich ein benutzerdefiniertes Formularfeld, die aktualisiert werden benötigt worden, um die übergeordnete Entität, nachdem alle zugeordneten Felder. Leider wird der POST_SUBMIT der untergeordneten Formulare aufgerufen, bevor SUBMIT für den übergeordneten Benutzer ausgeführt wird.

Ich landete das Eventdispatcher, um das Kind nach oben vorbei, und es meine Zuhörer zu binden. Ich brauchte zwei Listener, um die Aufgabe zu erledigen: einen, um den verarbeiteten Wert zu erhalten, und einen, um die Haupteinheit zu aktualisieren. Durch die Übergabe von $ generatedPassword an den Closure-Verweis können Sie Daten vom untergeordneten Ereignis an den übergeordneten Benutzer weitergeben.

parent :: buildForm

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

Kind :: 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 
    } 
} 

(Das benutzerdefinierte Feld ist eine Checkbox 'erzeugen neues Passwort speichern' markiert für ein Benutzer-Management-Modul. Es E-Mails der Benutzer das erzeugte Passwort, weshalb ich die aktuelle E-Mail-Adresse von der Haupteinheit benötigen)

+0

ist eine Idee, aber es bedarf noch die Mutterform zu ändern. Und wie die OP ich es nicht ändern kann. –

Verwandte Themen