miałem napisać samowystarczalne widget formularz, który wymaga JavaScript, udało mi się osiągnąć to, co staramy się robić poprzez event_dispatcher
słuchania na kernel.response
aby dołączyć JavaScript na koniec Symfony\Component\HttpFoundation\Response
. Oto fragment mojego typu forma:
<?php
namespace AcmeBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
class AcmeFileType extends AbstractType{
private $twig;
private $dispatcher;
public function __construct(\Twig_Environment $twig, EventDispatcherInterface $dispatcher){
$this->twig = $twig;
$this->dispatcher = $dispatcher;
}
public function buildView(FormView $view, FormInterface $form, array $options){
$javascriptContent = $this->twig->render('AcmeBundle:Form:AcmeFileType.js.twig', array());
$this->dispatcher->addListener('kernel.response', function($event) use ($javascriptContent) {
$response = $event->getResponse();
$content = $response->getContent();
// finding position of </body> tag to add content before the end of the tag
$pos = strripos($content, '</body>');
$content = substr($content, 0, $pos).$javascriptContent.substr($content, $pos);
$response->setContent($content);
$event->setResponse($response);
});
}
...
Podczas definiowania typ formularza w services.yml wygląda to tak:
acme.form.acme_file_type:
class: AcmeBundle\Form\AcmeFileType
arguments:
- @twig
- @event_dispatcher
tags:
- { name: form.type, alias: acmefile }
Więc teraz, za każdym razem budować formę z acmefile
javascript zostanie dodany do <body>
. To rozwiązanie nie przeszkadza javascript od bycia obecnym wiele razy, ale powinieneś być w stanie to poprawić w celu dostosowania do twoich potrzeb.
Można także bawić się obiektem $response
, aby zmodyfikować nagłówki zamiast tego, jeśli chcesz, w przypadku.
Dlaczego nie chcesz zmodyfikować szablonu bazowego? To * jest * miejscem, w którym należy ustawić pliki js \ css, które chcesz zaimportować. – tamir
Chcę utworzyć pakiet z rozszerzeniem widgetu, który sam się zawiera, i włączyć ten pakiet tylko raz w AppKernel.php. Co więcej, nie chcę dodawać js/css, jeśli widget nie ma zastosowania na bieżącej stronie. –
To wydaje się być brakującą funkcją w Symfony (do tej pory). Może powinniśmy zainspirować się z [mediów widgetu django] (https://docs.djangoproject.com/en/dev/topics/forms/media/#assets-as-a-static-definition), które obejmuje zasoby tylko raz, jeśli widget obecny –