我必须编写一个需要 javascript 的自包含表单小部件,我能够通过event_dispatcher
侦听kernel.response
将 javascript 附加到Symfony\Component\HttpFoundation\Response
. 这是我的表单类型的片段:
<?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);
});
}
...
当您在 services.yml 中定义表单类型时,它看起来像这样:
acme.form.acme_file_type:
class: AcmeBundle\Form\AcmeFileType
arguments:
- @twig
- @event_dispatcher
tags:
- { name: form.type, alias: acmefile }
所以现在,每次您使用 javascript 构建表单时acmefile
,都会将其附加到<body>
. 尽管此解决方案不会阻止javascript多次出现,但您应该可以轻松地对其进行改进以满足您的需求。
如果您愿意,您也可以使用$response
对象来修改标题。