Php Symfony2中表单中实体字段类型的附加属性

Php Symfony2中表单中实体字段类型的附加属性,php,forms,symfony,properties,entity,Php,Forms,Symfony,Properties,Entity,在Symfony2中,是否有一种方法可以将实体中的更多字段映射到基于实体的表单生成的选择下拉列表的选项标记 我目前有一些类似于: $builder->add('creditcard', 'entity', array( 'label' => 'Credit Card', 'required' => true, 'expanded' => false, 'class' =>

在Symfony2中,是否有一种方法可以将实体中的更多字段映射到基于实体的表单生成的选择下拉列表的选项标记

我目前有一些类似于:

    $builder->add('creditcard', 'entity',
        array( 'label' => 'Credit Card',
            'required' => true,
            'expanded' => false,
            'class' => 'Acme\Bundle\Entity\CreditCard',
            'property' => 'display_text',
            'multiple' => false,
            'query_builder' => function(\Acme\Bundle\Repository\CreditCardRepository $er)  {
                return $er->createQueryBuilder('b');
            },
            'mapped' => false,
        ));
<option value="id" string_mapped_from_field1="value_of_field1">display_text</option>
这很好,但我想生成如下内容:

    $builder->add('creditcard', 'entity',
        array( 'label' => 'Credit Card',
            'required' => true,
            'expanded' => false,
            'class' => 'Acme\Bundle\Entity\CreditCard',
            'property' => 'display_text',
            'multiple' => false,
            'query_builder' => function(\Acme\Bundle\Repository\CreditCardRepository $er)  {
                return $er->createQueryBuilder('b');
            },
            'mapped' => false,
        ));
<option value="id" string_mapped_from_field1="value_of_field1">display_text</option>
display\u文本

谢谢

好吧,如果有人带着同样的问题来到这里,这就是我最后所做的:

我已经创建了自定义字段类型(请参见)

由于我们最终将成为一个实体字段,您需要添加:

    public function getParent() {
        return 'entity';
    }
在表单上使用时:

    $builder->add('creditcard', new CreditCardFieldType(),
        array( 'label' => 'Credit Card',
            'required' => true,
            'expanded' => false,
            'class' => 'Acme\Bundle\Entity\CreditCardCharge',
            'property' => 'object',
            'multiple' => false,
            'query_builder' => function(\Acme\Bundle\Repository\CreditCardChargeRepository $er)  {
                return $er->createQueryBuilder('b');
            },
            'mapped' => false,
        ));
对象是添加到包含整个对象的实体的新属性,因此我添加到实体:

public function getObject()
{
    return $this;
}
通过这种方式,我们可以从模板访问对象,我们只需要为自己的自定义字段类型创建一个新模板:

{% block creditcard_widget %}
    {% spaceless %}
        {% if required and empty_value is none and not empty_value_in_choices %}
            {% set required = false %}
        {% endif %}
        <select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
            {% if empty_value is not none %}
                <option value=""{% if required and value is empty %} selected="selected"{% endif %}>{{ empty_value|trans({}, translation_domain) }}</option>
            {% endif %}
            {% if preferred_choices|length > 0 %}
                {% set options = preferred_choices %}
                {{ block('choice_creditcard_widget_options') }}
                {% if choices|length > 0 and separator is not none %}
                    <option disabled="disabled">{{ separator }}</option>
                {% endif %}
            {% endif %}
            {% set options = choices %}
            {{ block('choice_creditcard_widget_options') }}
        </select>
    {% endspaceless %}
{% endblock creditcard_widget %}

{% block choice_creditcard_widget_options %}
    {% spaceless %}
        {% for group_label, choice in options %}
            {% if choice is iterable %}
                <optgroup label="{{ group_label|trans({}, translation_domain) }}">
                    {% set options = choice %}
                    {{ block('choice_creditcard_widget_options') }}
                </optgroup>
            {% else %}
                <option value="{{ choice.data.creditcard }}" charge="{{  choice.data.charge }}" {% if choice is selectedchoice(data.creditcard_charges_id) %} selected="selected"{% endif %}>{{ choice.data.text|trans({}, translation_domain) }}</option>
            {% endif %}
        {% endfor %}
    {% endspaceless %}
{% endblock choice_creditcard_widget_options %}

我不确定这是最好的解决方案,但它确实奏效了。希望有帮助。

另一个解决方案是在CreditCardCharge实体上声明一个函数u toString()

比如:

public function __toString(){
   return $this->data1.'-'.$this->data2;
}
此函数必须返回字符串,用您的逻辑替换我的示例

并删除“属性”选项以默认使用此函数

$builder->add('creditcard', 'entity',
        array( 'label' => 'Credit Card',
            'required' => true,
            'expanded' => false,
            'class' => 'Acme\Bundle\Entity\CreditCard',
            'multiple' => false,
            'query_builder' => function(\Acme\Bundle\Repository\CreditCardRepository $er)  {
                return $er->createQueryBuilder('b');
            },
            'mapped' => false,
        ));

我试图在我的实体中使用这个示例,但我遇到了一个问题。它不会检测在页面加载后是否选择了某个值,并且在提交后该值不会保持不变

我觉得跟这一行有关系:

<option value="{{ choice.data.creditcard }}" charge="{{  choice.data.charge }}" {% if choice is selectedchoice(data.creditcard_charges_id) %} selected="selected"{% endif %}>{{ choice.data.text|trans({}, translation_domain) }}</option>
{{choice.data.text}trans({},translation\u domain)}
我不知道该放什么来代替:数据。信用卡收费\u id

这就是我的样子:

{% block emp_widget %}
    {% spaceless %}
        {% if required and empty_value is none and not empty_value_in_choices %}
            {% set required = false %}
        {% endif %}
        <select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
            {% if empty_value is not none %}
                <option value=""{% if required and value is empty %} selected="selected"{% endif %}>{{ empty_value|trans({}, translation_domain) }}</option>
            {% endif %}
            {% if preferred_choices|length > 0 %}
                {% set options = preferred_choices %}
                {{ block('choice_emp_widget_options') }}
                {% if choices|length > 0 and separator is not none %}
                    <option disabled="disabled">{{ separator }}</option>
                {% endif %}
            {% endif %}
            {% set options = choices %}
            {{ block('choice_emp_widget_options') }}
        </select>
    {% endspaceless %}
{% endblock emp_widget %}

{% block choice_emp_widget_options %}
    {% spaceless %}
        {% for group_label, choice in options %}
            {% if choice is iterable %}
                <optgroup label="{{ group_label|trans({}, translation_domain) }}">
                    {% set options = choice %}
                    {{ block('choice_emp_widget_options') }}
                </optgroup>
            {% else %}
                <option value="{{ choice.data.id }}" data-position="{{ choice.data.position }}" data-avatar="{% path choice.data.avatar, 'reference' %}" {% if choice is selectedchoice(choice.data.id) %} selected="selected"{% endif %}>{{ choice.data.firstname }} {{ choice.data.lastname }}</option>
            {% endif %}
        {% endfor %}
    {% endspaceless %}
{% endblock choice_emp_widget_options %}
{%block emp_widget%}
{%spaceless%}
{%if required and empty_value在_choices%}
{%set required=false%}
{%endif%}
{%如果空值不是none%}
{{empty_value}trans({},translation_domain)}
{%endif%}
{如果首选|长度>0%}
{%set options=首选选项%}
{{block('choice_emp_widget_options')}
{%如果选项|长度>0且分隔符不是none%}
{{分隔符}}
{%endif%}
{%endif%}
{%set options=choices%}
{{block('choice_emp_widget_options')}
{%endspaceless%}
{%endblock emp_widget%}
{%block choice\u emp\u widget\u options%}
{%spaceless%}
{%用于组_标签,选项%}
{%如果选择是可编辑的%}
{%set options=choice%}
{{block('choice_emp_widget_options')}
{%else%}
{{choice.data.firstname}{{choice.data.lastname}}
{%endif%}
{%endfor%}
{%endspaceless%}
{%endblock choice_emp_widget_options%}

我把它放在empField.php中修复了它:

{%- block choice_widget_options -%}
    {% for group_label, choice in options %}
        {%- if choice is iterable -%}
            <optgroup label="{{ group_label|trans({}, translation_domain) }}">
                {% set options = choice %}
                {{- block('choice_widget_options') -}}
            </optgroup>
        {%- else -%}
            <option value="{{ choice.value }}" data-position="{{ choice.data.position }}" data-avatar="{% path choice.data.avatar, 'reference' %}"{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice.data.fullname }}</option>
        {%- endif -%}
    {% endfor %}
{%- endblock choice_widget_options -%}
{%-block choice\u widget\u options-%}
{%用于组_标签,选项%}
{%-如果选择是可写的-%}
{%set options=choice%}
{{-block('choice_widget_options')-}
{%-else-%}
{{choice.data.fullname}
{%-endif-%}
{%endfor%}
{%-endblock choice_widget_options-%}
(它来自:\vendor\symfony\symfony\src\symfony\Bridge\Twig\Resources\views\Form\Form\u div\u layout.html.Twig)
而且它是有效的,我不确定这样做是否正确,但确实有效。

因为Symfony
2.7
您可以使用
choice\u attr

$builder->add('creditcard', 'entity',
    array( 'label' => 'Credit Card',

        // ...

       'choice_attr' => function($object, $key, $index) {
           return [
               'string_mapped_from_field1' => $object->getValueOfField1()
           ];
       },

    ));

我面临同样的问题,但还没有解决办法。如果我找到了,我会让你知道。在我的例子中,它缺少
value=“{{choice.data.id}}”
,所以整行是:
{{choice.data.location.name[app.request.locale].value}:{{choice.data.name[app.request.locale].value}
比Symfony 2.8中的主要答案快得多,也干净得多