【问题标题】:Symfony2 Form Component - creating fields without the forms name in the name attributeSymfony2 表单组件 - 在名称属性中创建没有表单名称的字段
【发布时间】:2011-12-07 14:19:27
【问题描述】:

我目前正在尝试通过 Silex 微框架使用 Symfony2 表单组件。

我的登录表单生成如下:

$app = $this->app;

$constraint = new Assert\Collection(array(
    'username' => new Assert\NotBlank(),
    'password' => new Assert\NotBlank(),
));

$builder = $app['form.factory']->createBuilder('form', $data, array('validation_constraint' => $constraint));

$form = $builder
    ->add('username', 'text', array('label' => 'Username'))
    ->add('password', 'password', array('label' => 'Password'))
    ->getForm()
;

return $form;

问题是生成的表单创建如下:

<fieldset>
    <input type="hidden" value="******" name="form[_token]" id="form__token">
    <section class="">
        <label class=" required" for="form_username">Username</label>
        <div><input type="text" value="" name="form[username]" id="form_username" class="text"></div>
    </section>
    <section class="">
        <label class=" required" for="form_password">Password</label>
        <div><input type="password" value="" name="form[password]" id="form_password" class="password"></div>
    </section>
    <section>
        <div><button class="fr submit">Login</button></div>
    </section>
</fieldset>

而我希望 name 和 id 属性如下:

<div><input type="text" value="" name="username" id="username" class="text"></div>
...
<div><input type="password" value="" name="password" id="password" class="password"></div>

我在网上搜索并发现了有关“property_path”选项的建议,但我相信这与在实际 Symfony2 框架本身中使用时用于处理数据的类有关。

我已经浏览了表单组件文件,并且设置的点在:

Symfony/Component/Form/Extension/Core/Type/FieldType.php - 第 71 行

public function buildView(FormView $view, FormInterface $form)
{
    $name = $form->getName();

    if ($view->hasParent()) {
        $parentId = $view->getParent()->get('id');
        $parentFullName = $view->getParent()->get('full_name');
        $id = sprintf('%s_%s', $parentId, $name);
        $fullName = sprintf('%s[%s]', $parentFullName, $name);
    } else {
        $id = $name;
        $fullName = $name;
    }
    ...

不幸的是,FormFactory 使用了 FormBuilder,然后它与 Form 类一起工作,我没有足够的时间来分析组件的整个内部工作原理。

我知道字段被添加到 FormBuilder 中的“子”数组中,并带有相应的选项列表。调用 getForm 函数时,会实例化一个新的 Form,并使用 add() 方法将每个子 FieldType 输入到 Form 中。这个 Form->add() 方法自动将 Form 设置为每个孩子的父级:

public function add(FormInterface $child)
{
    $this->children[$child->getName()] = $child;

    $child->setParent($this);

    if ($this->dataMapper) {
        $this->dataMapper->mapDataToForm($this->getClientData(), $child);
    }

    return $this;
}

没有开始重写这些类只是为了删除它,还有其他人知道只显示字段名称的最佳方法吗?

可以在 form_div_layout.html.twig widget_attributes 块中只提取“name”而不是“full_name”,但我不确定这是否理想(因为 id 保持不变)或者是否有另一个可以解决问题的方法或可注入选项。

【问题讨论】:

    标签: forms symfony silex


    【解决方案1】:

    在 Symfony3 中,覆盖子类中的 AbstractType::getBlockPrefix 以返回 null。

    【讨论】:

      【解决方案2】:

      使用 createBuilder 函数代替:

      $builder = $app['form.factory']->createNamedBuilder(null, 'form', $data, array('validation_constraint' => $constraint));
      

      第一个参数是表单名称。

      Bernhard Schussek 本人在https://stackoverflow.com/a/13474522/520114 的示例

      【讨论】:

      • 啊哈,现在我为什么不看 github,那是有道理的。谢谢:)
      • 啊哈!您已更新您的答案 - 一个理想的解决方案!谢谢
      • 在使用 FormTypes 作为服务时是否可以这样做?我认为您无法在该上下文中访问 c​​reateNamedBuilder 并使用 FormType::getName() { return ''; } 导致将 FormType 引用为服务的问题。
      • @caponica 完全正确。你有什么办法吗?
      • @mmoreram - 是的,Bernhard 指出(在另一个线程上)这很容易:stackoverflow.com/questions/13384056/… 你只需使用 $builder->getFormFactory() (我已经有一段时间没有看到这个了,所以不要'不记得手头的细节!)
      【解决方案3】:

      如果您不使用子表单,您可以将表单的getName 方法设置为空字符串:

      class FormType extend AbstractType {
          // ...
      
          public function getName() {
              return '';
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-09-11
        • 1970-01-01
        • 2021-11-19
        • 2013-02-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-13
        相关资源
        最近更新 更多