Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Symfony2中的自定义表单字段,继承了不需要的属性_Symfony_Symfony Forms - Fatal编程技术网

Symfony2中的自定义表单字段,继承了不需要的属性

Symfony2中的自定义表单字段,继承了不需要的属性,symfony,symfony-forms,Symfony,Symfony Forms,我在理解Symfony2自定义表单字段类型如何工作时遇到一些困难。我需要根据传递给MyType的数据创建一个具有一些自定义属性的新类型(HTML5data-*) 问题在于将MyType添加到主窗体后,其标签继承了data-*属性 // Add MyType to the main form $builder->add('somename', new MyType(), array('label' => 'my label')); 这是我的自定义类型: class MyType e

我在理解Symfony2自定义表单字段类型如何工作时遇到一些困难。我需要根据传递给
MyType
的数据创建一个具有一些自定义属性的新类型(HTML5
data-*

问题在于
MyType
添加到主窗体后,其标签继承了
data-*
属性

// Add MyType to the main form

$builder->add('somename', new MyType(), array('label' => 'my label'));
这是我的自定义类型:

class MyType extends AbstractType
{

    public function getDefaultOptions(array $options)
    {
       $source = isset($option['source']) ? json_encode($option['source']) : '';

        return array(
            'attr' => array(
                'data-source' => $source
            )
        );
    }

    public function getName() { return 'mytype'; }

    public function getParent(array $options) { return 'text'; }

}

所以基本的问题是标签会拾取小部件上的所有属性。我真的不明白他们为什么这样设计,但如果你看看:

{# Symfony/Bridge/Twig/Resources/Form/form_div_layout.html.twig #}
{% block generic_label %}
{% spaceless %}
    {% if required %}
        {% set attr = attr|merge({'class': attr.class|default('') ~ ' required'}) %}
    {% endif %}
    <label{% for attrname,attrvalue in attr %} {{attrname}}="{{attrvalue}}"{% endfor%}>{{ label|trans }}</label>
{% endspaceless %}
{% endblock %}

EDIT:据我所知,将
array('attr'=>array('myattr1'=>'value1'))
作为生成器的选项用于生成器及其所有子元素的公共属性。这就是为什么,例如,在表单级别传递
array('required'=>false)
将禁用该表单中每个字段的HTML5内置客户端验证

(一直在寻找更好的解决方案)我将发布我的方法,灵感来自于:一个带有查看属性的自定义表单字段,以及一个创建新属性的小树枝块

class TypeheadType extends AbstractType
{

    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            ->setAttribute('mode',  $options['mode'])
            ->setAttribute('items', $options['items']);

    }

    public function buildView(FormView $view, FormInterface $form)
    {

        $view
            ->set('mode',  $form->getAttribute('mode'))
            ->set('items', $form->getAttribute('items'));
    }

    public function getDefaultOptions(array $options)
    {

        return array(
            'mode'  => 'single',
            'items' => 10
        );
    }

    public function getName() { return 'typehead'; }

    public function getParent(array $options) { return 'field'; }

}
新表单类型应注册为服务,别名应与
getName()
返回的内容匹配(这是必需的吗?不知道…):

新字段创建(其他位置):

在Twig表单主题小部件块中(名称的模式是
作为getName()。\u小部件
),您可以使用在
TypeheadType
中设置的视图属性:

{% block typehead_widget %}
{% spaceless %}
    <input type="text" {{ block('widget_attributes') }} 
        {% if value is not empty %}value="{{ value }}" {% endif %}
        data-items="{{ items }}" data-mode="{{ mode }}" />
{% endspaceless %}
{% endblock typehead_widget %}

确认一下,您是说您的标签html实体在呈现时以数据源属性结尾吗?如果是这样的话,我可以帮忙。如果是其他东西,则可能不是。@Cerad是的,标签的属性与小部件完全相同。请投票支持小树枝解决方案,谢谢。但我已经找到了一个更好的,我会尽快发布。期待看到替代解决方案。我的解决方案是有效的,但正如我所说的,我总觉得我遗漏了一些明显的东西。回复贴出,让我知道你对此有何看法。谢谢
class TypeheadType extends AbstractType
{

    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            ->setAttribute('mode',  $options['mode'])
            ->setAttribute('items', $options['items']);

    }

    public function buildView(FormView $view, FormInterface $form)
    {

        $view
            ->set('mode',  $form->getAttribute('mode'))
            ->set('items', $form->getAttribute('items'));
    }

    public function getDefaultOptions(array $options)
    {

        return array(
            'mode'  => 'single',
            'items' => 10
        );
    }

    public function getName() { return 'typehead'; }

    public function getParent(array $options) { return 'field'; }

}
form.type.typehead:
  class: Acme\HelloBundle\Form\Type\TypeheadType
  tags:
    - { name: form.type, alias: typehead }
$builder->add('myfield', 'typehead', array('items' => 15));
{% block typehead_widget %}
{% spaceless %}
    <input type="text" {{ block('widget_attributes') }} 
        {% if value is not empty %}value="{{ value }}" {% endif %}
        data-items="{{ items }}" data-mode="{{ mode }}" />
{% endspaceless %}
{% endblock typehead_widget %}
{{ form_row(form.myfield) }}