“中国要复兴、富强,必须在开源软件领域起到主导作用,为了国家安全和人类发展,责无旁贷,我们须为此而奋斗”——By:云客
Drupal表单功能非常强大且灵活,但是如果不十分清楚内部处理原理那么会遇到一些让新手摸不着头脑的问题,以下以表单对象的属性取赋值问题来说明
有如下一个表单:
<?php
/**
 * 演示表单对象属性取值赋值问题
 */
namespace Drupal\yunke_help\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
class YunkeForm extends FormBase {
  protected $name = NULL;
  protected $company = NULL;
  public function getFormId() {
    return 'yunke_help_form';
  }
  public function buildForm(array $form, FormStateInterface $form_state) {
    $this->name = 'yunke';
    $form['name'] = [
      '#type'          => 'textfield',
      '#title'         => 'name',
      '#default_value' => $this->name,
      '#attributes'    => [
        'autocomplete' => 'off',
      ],
    ];
    $form['view'] = [
      '#type'  => 'button',
      '#value' => 'view',
      '#ajax'  => [
        'callback' => '::report',
        'wrapper'  => 'report-result-wrapper',
        'prevent'  => 'click',
        'method'   => 'html',
        'progress' => [
          'type'    => 'throbber',
          'message' => 'load...',
        ],
      ],
    ];
    $form['view2'] = [
      '#type'  => 'submit',
      '#value' => 'submit',
      '#ajax'  => [
        'callback' => '::report',
        'wrapper'  => 'report-result-wrapper',
        'prevent'  => 'click',
        'method'   => 'html',
        'progress' => [
          'type'    => 'throbber',
          'message' => 'load...',
        ],
      ],
    ];
    $form['content'] = [
      '#type'       => 'container',
      '#optional'   => FALSE,
      '#attributes' => ['id' => 'report-result-wrapper'],
    ];
    return $form;
  }
  public function report(array &$form, FormStateInterface $form_state) {
    return [
      '#markup' => 'report:' . $this->name . ' ' . $this->company,
    ];
  }
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $this->name = $form_state->getValue('name');
    $this->company = 'will-nice';
  }
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $this->messenger()->addStatus('submit(name):' . $this->name);
  }
}
运行该表单后,随意输入一个值,分别点击两个按钮看看会有什么不同
你会发现点击提交按钮时, $this->name成功覆写,而点击非提交按钮时,不会覆写
为什么会出现这种情况呢?
其实在非提交按钮进行的ajax提交中,验证处理器运行后,会进入重建表单逻辑,由此构建表单方法buildForm会被再执行一次,也就是说在上例中虽然验证器修改了$this->name的值,但由于buildForm会被再执行一次,所以又被改回去了,而 $this->company不受影响
在提交按钮进行的ajax提交中,验证处理器运行后,如果无验证错误,会继续执行提交处理器,之后不会进入重建表单逻辑,直接执行ajax回调方法
交流互动