Symfony 2自定义表单字段类型:如何只添加一次javascript和css?

Ily*_*kov 18 forms symfony twig

我想在自定义Symfony 2表单字段类型扩展中使用javascript.所以,我有这样的Twig扩展模板:

{% block some_widget %}
    <input ... />

    <script src="some.js"></script>
    <link href="some.css" />
{% endblock %}
Run Code Online (Sandbox Code Playgroud)

但是我想在我的HTML中只使用这些脚本和链接标记一次,理想情况是在head标记中,而不需要修改基本模板.我试图扩展Twig块,但我无法访问表单模板中的动作模板块.或者类似这样的事情:

{# widget tempate #}
{% block some_widget %}
    <input ... />

    {{ use_javascript('some.js') }}
    {{ use_css('some.css') }}
{% endblock %}

{# main action template #}
...
<head>
{{ dump_javascripts() }}
{{ dump_css() }}
</head>
...
Run Code Online (Sandbox Code Playgroud)

如何使用Symfony 2 Forms + Twig?

PS抱歉我的英语不好.

小智 9

我不得不写一个自包含的表单小部件,需要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);
    });

  }

  ... 
Run Code Online (Sandbox Code Playgroud)

在services.yml中定义表单类型时,它看起来像这样:

acme.form.acme_file_type:
    class: AcmeBundle\Form\AcmeFileType
    arguments:
        - @twig
        - @event_dispatcher
    tags:
        - { name: form.type, alias: acmefile }
Run Code Online (Sandbox Code Playgroud)

所以现在,每次使用acmefilejavascript 构建表单都会附加到<body>.此解决方案不会阻止 javascript 多次出现,但您应该能够轻松地根据自己的需要进行改进.

如果您愿意,您也可以使用$response对象来修改标题.

  • 您应该将 `if (!$event-&gt;isMasterRequest()) return;` 添加到 `kernel.response` 侦听器中,以避免将此代码段添加到每个子请求/响应中。 (2认同)

Axx*_*iss 0

我就是这样使用的。希望这是您正在寻找的。

base.html.twig

<head>
   {% block stylesheets %}
       css...
   {% endblock %}
</head>
Run Code Online (Sandbox Code Playgroud)

foo.html.twig

{% extends '::base.html.twig' %}

{% block stylesheets %}
   {{ parent() }}

   css that you need in foo.html.twig

{% endblock %}
Run Code Online (Sandbox Code Playgroud)

  • 是的,这是常规视图模板的常用方法(我使用它)。但这不适用于表单类型模板。 (2认同)