【问题标题】:Unable to access form values in array with key-array subset无法使用键数组子集访问数组中的表单值
【发布时间】:2017-12-20 10:29:13
【问题描述】:

对于我正在与地址与该公司相关的公司工作的项目。我为公司创建了一个带有物理地址的表单(这个地址总是存在的,它也有与之关联的额外地址。这就是我遇到问题的地方。

我对表单使用 CollectionType,以便为每个额外的地址使用相同的表单。 我正在使用以下方法为额外地址(可以是 1、2、3 甚至 4 个地址)创建一个带有预填充值的表单:

    $form_adressen = $this
        ->createForm(AdressenType::class, $result['extra_address'])
        ->handleRequest($request)
    ;

但是,这不会呈现表单,也不会从控制器中获取任何值。 但是,以下代码有效:

    $form_adressen = $this
        ->createForm(AdressenType::class, $result)
        ->handleRequest($request)
    ;

结果['extra_address'] 打印以下数据:

Array
(
    [1059] => Array
        (
            [AdrGid] => 1059
            [AdrCode] => the address type
            [AdrStraat] => streetname
            [AdrHuisnummer] => number
            [AdrPostcode] => postal code
            [AdrPlaats] => cityname
            [AdrTelefoon] => telephone
            [AdrTelefoon2] => mobile
            [AdrTelefax] => fax
            [AdrNawGid] => 332 //id of companyaddress associating to this 'extra' address
            [NawFactuurAdres] => 1
            [AdrOms] => address type description
        )
        [...] // More addresses
}

$result 给了我这个:

Array
(
    [company] => Array
        (
            [AdrGid] => 332
            [NawFilZoekcode] => company code
            [AdrNaam1] => company name
            [email2] => company mail
            [NawWebsite] => company website
            [email1] => second company email
            [AdrStraat] => streetname
            [AdrHuisnummer] => number
            [AdrPostcode] => postal code
            [AdrPlaats] => cityname
            [LndOms] => country
            [AdrTelefoon] => telephone
            [AdrTelefoon2] => mobile
            [AdrTelefax] => fax
            [NawFactuurAdres] => 1
            [AdrCode] => adrress type
            [AdrOms] => address type description
        )

    [extra_address] => Array
        (
            [1059] => Array
                (
                    [AdrGid] => 1059
                    [AdrCode] => address type
                    [AdrStraat] => streetname
                    [AdrHuisnummer] => number
                    [...] // etc etc

我的结果数组如下所示:

foreach ($company as $row) {
    $dataFields = [
        [...]
    ];
    foreach ($dataFields as $dataField) {
        if (empty($result['gegevens'][$dataField])) {
            $result['company'][$dataField] = $row[$dataField];
        }
    }
    if ($row['AdrGid'] != $result['gegevens']['AdrGid']) {
        $result['extra_address'][$row['AdrGid']] = [
            [...]
        ];
    }
}

编辑: 我的 AdressenType 创建表单:

class AdressenType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('addresses', CollectionType::class, [
                'entry_type' => AddressType::class
            ])
        ;
    }
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
        ));
    }
    public function getBlockPrefix()
    {
        return 'appbundle_form_adressenform';
    }
}
class AddressType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            [...] // Add fields
        ;
    }
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
        ));
    }
}

这就是我将表单传递给视图的方式:

return $this->render('pages/company/edit.html.twig', array(
    'client' => $result,
    'form' => $form->createView(),
    'form_adressen' => $form_adressen->createView()
));

正如您所见,extra_address 循环使用 id 作为数组的键,我想这就是地址没有显示或呈现在视图中的原因。

我使用以下代码遍历每个表单:

{{ form_start(form_adressen, {'  method': 'POST'}) }}
{{ form_row(form_adressen._token) }}
{% for adres in form_adressen.addresses %} // here 'addresses' is my form collectionType, not to be confusing
    [...] // form_widgets, etc
{{ endfor }}
{{ form_end(form_adressen) }}

form_adressen 是我的 formType 名称,“addresses”是我的 form_adressen formType 的 collectionType。

我的问题是,如果地址表单有一个 id 作为每个地址的数组的键,我该如何填写地址表单?我的猜测是表单无法识别键,所以它会跳过。

【问题讨论】:

    标签: php arrays forms symfony twig


    【解决方案1】:

    当前的AdressenType 尝试在['addresses'] 找到它的数据,但在控制器中,您通过直接传入额外地址列表来创建表单。

    ->createForm(AdressenType::class, $result['extra_address'])
    

    此数组可能没有键 'addresses',因此表单的行为就像不存在条目一样。

    所以要么:

    1. 传入正确的数据:

      ->createForm(AdressenType::class, [
          'addresses' => $result['extra_address']
      ])
      
    2. AdressenType中的key改为'extra_address'并传入$result

      $builder
          ->add('extra_address', CollectionType::class, [
              'entry_type' => AddressType::class
          ])
      ;
      

      ->createForm(AdressenType::class, $result)
      
    3. 或者更好,更改AdressenType 以直接扩展CollectionType。哪个(恕我直言)是更好/更清洁的事情,因为它消除了对任意数组键的依赖:

      <?php
      // ...
      use Symfony\Component\Form\Extension\Core\Type\CollectionType;
      
      class AdressenType extends AbstractType
      {
          /**
           * @inheritdoc
           */
          public function configureOptions(OptionsResolver $resolver)
          {
              $resolver->setDefaults([
                  'entry_type' => AddressType::class,
              ]);
          }
      
          /**
           * @inheritdoc
           */
          public function getParent()
          {
              // extend the collection type
              return CollectionType::class;
          }
      }
      

      与:

      ->createForm(AdressenType::class, $result['extra_address'])
      

      在视图中,您可以将其用作:

      <h4>Extra addresses</h4>
      {{ form_start(form_adressen) }}
          {% for address in form_adressen.children %}
              {{ form_errors(address) }}
              {{ form_widget(address) }}
              <br>
          {% endfor %}
      
          <button>Submit</button>
      {{ form_end(form_adressen) }}
      

    使用第三个选项,您在尝试自定义表单呈现时可能会遇到问题。像这样使用自动注入的 csrf-token 将是地址的兄弟。如果您尝试访问每个子项的各个字段,这可能会导致错误。

    虽然在这种情况下以下应该有效:

    {% for key, value in form_adressen.vars.data %}
        {{ form_row(form_adressen.children[key].AdrStraat) }}
        {{ form_row(form_adressen.children[key].AdrHuisnummer) }}
        {{ form_row(form_adressen.children[key].AdrPostcode) }}
        <br>
    {% endfor %}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-02
      • 1970-01-01
      • 2020-12-04
      • 1970-01-01
      • 1970-01-01
      • 2012-03-23
      • 2010-10-18
      相关资源
      最近更新 更多