在Symfony2中自定义选择/实体字段的呈现

Lev*_*zél 9 php customization rendering symfony

我希望<select>在其<option>s 上添加其他数据的元素.为了举例,我想要一个服务选择器(非多实体字段),在选择更改时重置另一个输入值.我对使用JS数据结构不感兴趣,我需要将渲染字段看起来如下所示:

<select name="...">
    <option value="1" data-price="90">Service 1</option>
    <option value="2" data-price="40">Service 2</option>
</select>
Run Code Online (Sandbox Code Playgroud)

我会采取两种不同的解决方案,并很高兴看到他们两个的答案.

  1. 我通过使用form传递给树枝的变量开始组装上面的HTML代码,在Twig中手动渲染字段.解决这个问题我有两个问题.A)我找不到一种安全的方法来告诉应该命名的name字段,即如何通过使用变量获得Symfony期望的属性form.service(service是FormType中字段的名称).[请告诉我根据Symfony 目前如何命名字段来连接一些值的技巧; 一个人应该依赖接口而不是逆向工程.] B)我不知道如何访问选择列表,即由entity字段query_builder选项组装的数组.[由于我正在寻找一般解决方案,我不愿意将这些项目复制到控制器中的twig参数 - 只是为了避免这些建议.]
  2. 我会覆盖相关字段块的渲染,如在食谱的样式章节中所建议的那样,但是有三个问题.A)我无法找出应该覆盖哪些块(因此我找不到样本).B)我会将参数从表单生成器传递给块,让它知道data-要渲染的额外属性,但我不知道如何做到这一点.最后C)在那些我不需要偏离标准渲染的情况下(例如当字段是多个时)我不知道如何回退到默认渲染.

所以这些实际上是5个问题(1A,1B,2A,2B,2C),但我认为它们对其他人一起回答更有用,因为它们都解决了我认为关于选择场渲染的无证问题.

Ale*_* B. 16

1.手动渲染.更好,如果是一个单独的字段形式,而不是重复一些,因为它需要较少的工作时间.

A)获取可以使用的字段名称form.service.vars.full_name

B)选择清单 - form.service.vars.choices.它是一个数组ChoiceView,让实体只需访问公共data财产.

{% for choice in form.service.vars.choices %}
    {% set service_entity = choice.data %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

2.通过覆盖模板.如果你想蛮力拿起必须覆盖的街区的名称.

A)您只能覆盖widget,label并且errors块作为文档说.您可以按窗口小部件名称(文档)指定.就像是

{% block _form_service_widget %}
    {% if expanded %}
        {{ block('choice_widget_expanded') }}
    {% else %}
        {{ block('my_service_widget') }}
    {% endif %}
{% endblock %}

{% block my_service_widget %}
{% spaceless %}
    <select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
        {% if empty_value is not none %}
            <option value="">{{ empty_value|trans({}, translation_domain) }}</option>
        {% endif %}
        {% set options = choices %}
        {{ block('my_service_options') }}
    </select>
{% endspaceless %}
{% endblock my_service_widget %}

{% block my_service_options %}
{% spaceless %}
    {% for group_label, choice in options %}
        {# here you can access choice #}
        <option value="{{ choice.value }}"{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice.label|trans({}, translation_domain) }}</option>
    {% endfor %}
{% endspaceless %}
{% endblock my_service_options %}
Run Code Online (Sandbox Code Playgroud)