雲客Drupal源碼分析之系統AJAX(一):概述與示例

這是很多讀者期待的一個激動人心的時刻,從本篇起,本系列將分多集連續全面介紹Drupal系統的AJAX實現,在閱讀前需要掌握一些必須的前置知識,請先閱讀本系列以下主題:

 《全局設置與前端API》

 《jQuery表單庫jquery.form.js詳解》

此外需要讀者熟悉jQuery,如果JS編程不熟悉,雲客爲你準備了以下教程:

 《PHP開發者的JavaScript快速教程(phper簡明js教程)》

 

Drupal AJAX概述:

AJAX是在不刷新整個頁面的前提下,基於服務器端返回的數據動態更新頁面中部分內容或JS變量的過程;在drupal世界中從開發角度看AJAX,可分爲兩大類:

自定義AJAX:

和通常項目一樣的由開發者自定義前端js代碼,再從後端拉取數據實現的AJAX,這要求開發者自定義資源庫,爲了方便通常會依賴核心jquery庫,用jquery提供的諸多方法進行AJAX通訊;這一類AJAX靈活自由,可以實現開發者想要的任意功能,是一種任意項目通用的底層操作,而不侷限於drupal,缺點是需要開發者處理所有細節,不夠簡單和便捷,即便一個小功能也需要實現自定義庫。

Drupal AJAX API:

  爲彌補第一類的不足,系統提供了AJAX API,非常便捷、簡單,無需寫JS代碼,只需要依據API的要求爲要應用AJAX行爲的元素指定一個AJAX配置即可,無需涉及底層細節,系統會自動完成AJAX功能,這是一種更高層級的封裝,支持任意元素。

  通常最常見的AJAX操作是從服務器拉取html片段並替換頁面元素,但也有很多其他操作,比如依據服務器返回的數據更新某個js變量、彈出一個警告框、設置一個css屬性、移除一個元素等等,Drupal將各種操作進行了統一,透過現象直達本質,在實現上,將不同種類的操作抽象成一個個不同的命令,每個命令由一個對應的js函數來完成該種操作,比如替換html就是一個“insert”命令,參數是替換的html片段以及如何替換、替換誰等;這樣一來,後端僅需以json方式返回一個純數據對象即可,對象中包含了命令的名字,以及完成命令需要的參數數據,在前端該對象稱爲AJAX命令對象,後端僅返回AJAX命令對象,且在一次AJAX請求中可以返回多個命令,從而一次性進行多種操作,關於命令會在後續主題詳細解釋。

  API的缺點是如果系統提供的AJAX命令不能滿足需求,那麼需要新增命令,但很棒的是系統默認提供的命令足夠豐富且擴展簡單。

 

在設計上AJAX API主要用於以下元素:

渲染數組中具備“#ajax”屬性的表單元素

具備“use-ajax”類屬性的鏈接元素

具備“use-ajax-submit” 類屬性的表單按鈕

但這並不是說僅能用於這些元素,準確的說法是最常用於這些元素,AJAX API是可以用於任意元素的,見下文示例三的說明。

 

準備:

爲演示本篇的示例,需要一個模塊來運行相關代碼,這裏以“yunke_help”模塊爲列,該模塊是本系列的配套模塊,專門用於研究學習drupal,有非常多的輔助功能,請先到雲客的博客下載安裝,須注意這裏只是爲了起演示作用,並不依賴特定模塊,以下以“yunke_help”模塊來說明示例步驟。

 

示例一:在表單非提交元素上運用AJAX

目的:一個表單元素輸入改變,從服務器獲取數據聯動改變其他元素

第一步:

建立文件:yunke_help/src/Form/YunkeForm.php

內容如下:

<?php
/**
 * 演示表單AJAX操作
 */

namespace Drupal\yunke_help\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class YunkeForm extends FormBase
{
    public function getFormId()
    {
        return 'yunke_help_form';
    }

    public function buildForm(array $form, FormStateInterface $form_state)
    {
        $form['content_one'] = [
            '#type'       => 'html_tag',
            '#tag'        => 'div',
            '#value'      => 'ajax獲取的內容將顯示在這裏:',
            '#attributes' => ['id' => 'content_one'],
        ];
        $form['input'] = [
            '#type'        => 'textfield',
            '#title'       => '任意輸入字符:',
            '#description' => '輸入的內容將通過ajax發送到服務器',
            '#size'        => '60',
            '#ajax'        => [
                'callback' => '::yunkeTest',
                'event'    => 'blur',
                'wrapper'  => 'content_one',
                'method'   => 'append',
                'effect'   => 'slide',
                'speed'    => 1000,
                'prevent'  => 'click',
                'progress' => [
                    'type'    => 'throbber',
                    'message' => '正在進行ajax...',
                ],
            ],
        ];

        $form['#attributes']['target'] = "_blank";
        $form['actions']['#type'] = 'actions';
        $form['actions']['submit'] = array(
            '#type'        => 'submit',
            '#value'       => $this->t('Submit'),
            '#button_type' => 'primary',
        );
        return $form;
    }

    public function yunkeTest(array &$form, FormStateInterface $form_state)
    {
        //\Drupal::messenger()->addStatus('AJAX消息測試'); //默認也會發生消息管理器中的內容
        $markup = '你的輸入是:' . $form_state->getValue('input') . '<br>';
        return ['#markup' => $markup];
    }

    public function validateForm(array & $form, FormStateInterface $form_state)
    {
    }

    public function submitForm(array & $form, FormStateInterface $form_state)
    {
        $form_state->cleanValues();
        print_r($form_state->getValues());
        die;
    }
}

第二步:

然後在控制器:\Drupal\yunke_help\Controller\Test::test中執行以下代碼:

return \Drupal::formBuilder()->getForm("\Drupal\yunke_help\Form\YunkeForm");

訪問連接:http://www.你的域名.com/yunke-help/test

或點擊“yunke_help”模塊主頁的測試按鈕

說明:

在該例中關鍵在於表單元素的“#ajax”項設置,她爲前端提供了一個AJAX配置,前端系統會據此爲具備該屬性的元素附加AJAX行爲,AJAX配置可用的設置項及解釋見下文的AJAX配置說明。

 

示例二:在dialog彈框顯示鏈接內容

目的:點擊頁面中的鏈接,然後將鏈接內容通過AJAX獲取後顯示到頁面dialog彈框中:

第一步:

先在控制器:\Drupal\yunke_help\Controller\Test::test_1中放入以下內容供AJAX獲取:

        $msg = '<div>我是ajax獲取的內容' . time() . '</div>';
        return array(
            '#markup' => $msg,
        );

第二步:

然後在控制器:\Drupal\yunke_help\Controller\Test::test中執行以下示例代碼:


        $elements['#title'] = '示例二:用dialog顯示鏈接目標';
        $url = \Drupal\Core\Url::fromUri('internal:/yunke-help/test-1');
        $elements['link'] = [
            '#type'       => 'link',
            '#title'      => '點擊本鏈接將以dialog方式打開',
            '#url'        => $url,
            '#attributes' => ['class'            => ['use-ajax'],
                              'data-dialog-type' => 'dialog',
            ],
        ];
        return $elements;

第三步:

這樣就可以點擊“yunke_help”模塊主頁的測試按鈕查看示例效果了

說明:

該例沒有像示例一那樣用到“#ajax”屬性,沒有AJAX配置傳遞到前端,但是前端系統發現鏈接具備類屬性“use-ajax”就會結合 “data-dialog-type” 屬性、href屬性自動產生AJAX配置並附加AJAX行爲

 

示例三:點擊鏈接後在任意位置顯示

目的:示例二以dialog顯示AJAX獲取的內容,本例將獲取的內容顯示到特定的頁面元素中

第一步:

示例二中控制器:\Drupal\yunke_help\Controller\Test::test_1中所放AJAX獲取的內容不變

然後在控制器:\Drupal\yunke_help\Controller\Test::test中執行以下示例代碼:

        $elements['#title'] = '示例三:在特定元素中顯示鏈接目標';
        $elements['content_one'] = array(
            '#type'       => 'html_tag',
            '#tag'        => 'div',
            '#value'      => '容器元素',
            '#attributes' => ['id' => 'content_one'],
        );
        $url = \Drupal\Core\Url::fromUri('internal:/yunke-help/test-1');
        $elements['link'] = [
            '#type'       => 'link',
            '#title'      => '點擊本鏈接將在容器元素中呈現目標內容',
            '#url'        => $url,
            '#attributes' => ['id' => 'yunkeID'],
        ];
        $elements['link']['#attached']['drupalSettings']['ajax']['yunkeID'] = [ //以鏈接ID做鍵名
            'event'    => 'click',
            'wrapper'  => 'content_one', //賦值容器元素ID,以使得顯示位置指向容器元素
            'method'   => 'append',
            'effect'   => 'slide',
            'speed'    => 1000,
            'prevent'  => 'click',
            'progress' => [
                'type'    => 'throbber',
                'message' => '正在進行ajax...',
            ],
        ];
        $elements['link']['#attached']['drupalSettings']['ajaxTrustedUrl'][$url->toString()] = TRUE;
        $elements['link']['#attached']['library'][] = 'core/jquery.form';
        $elements['link']['#attached']['library'][] = 'core/drupal.ajax';
        return $elements;

第二步:

這樣就可以點擊“yunke_help”模塊主頁的測試按鈕查看示例效果了

說明:

在該例中關鍵在於通過系統前端設置機制傳遞了一個AJAX配置,這以觸發AJAX事件元素的id做鍵名(這裏是yunkeID),鍵值是AJAX配置,該配置和示例一中的“#ajax”是一樣的,實際上在內部,示例一中的“#ajax”也會被轉化成這種形式,這裏使用了更加底層的操作,由於沒有采用自動處理,因此必須手動附加相關的庫和可信AJAX請求鏈接設置

以示例三這種方法可以爲任意前端元素指定AJAX行爲,如圖片、按鈕、文字等等,只需要元素具備ID屬性,並以ID屬性值做AJAX配置的鍵名即可,但需要注意由於本例中觸發AJAX的元素是一個鏈接元素(a標籤),AJAX請求url可以被前端系統從鏈接上自動獲取,因此可以省略,如果是其他元素,那麼必須在配置中指定url項,其值必須是一個字符串值,不能是url對象,如果是url對象必須用“$url->toString()”進行轉化

 

示例四:在任意元素上設置AJAX行爲

目的:在任意元素上設置AJAX行爲,並將結果顯示在對話框中,這裏以span元素爲列

第一步:

前例控制器:\Drupal\yunke_help\Controller\Test::test_1中所放AJAX獲取的內容不變

然後在控制器:\Drupal\yunke_help\Controller\Test::test中執行以下示例代碼:

        $elements['#title'] = '示例四:任意元素觸發AJAX,並在dialog中顯示內容';
        $url = \Drupal\Core\Url::fromUri('internal:/yunke-help/test-1');
        $elements['span'] = [
            '#type'       => 'html_tag',
            '#tag'        => 'span',
            '#value'      => '點擊這裏將在dialog中呈現ajax內容',
            '#attributes' => ['id' => 'yunkeID'],

        ];
        $elements['link']['#attached']['drupalSettings']['ajax']['yunkeID'] = [ //以觸發元素ID做鍵名
            'event'      => 'click',
            'dialogType' => 'dialog', //該項使得顯示位置在對話框中
            'url'        => $url->toString(),
            'method'     => 'append',
            'effect'     => 'slide',
            'speed'      => 1000,
            'prevent'    => 'click',
            'progress'   => [
                'type'    => 'throbber',
                'message' => '正在進行ajax...',
            ],
        ];
        $elements['link']['#attached']['drupalSettings']['ajaxTrustedUrl'][$url->toString()] = TRUE;
        $elements['link']['#attached']['library'][] = 'core/jquery.form';
        $elements['link']['#attached']['library'][] = 'core/drupal.ajax';
        return $elements;

第二步:

這樣就可以點擊“yunke_help”模塊主頁的測試按鈕查看示例效果了

說明:

該例的目的是讓讀者明白drupal的AJAX API可以用於任意元素,這裏僅以span元素的點擊事件爲例

 

示例五:通過AJAX提交表單

目的:在表單提交元素上設置AJAX行爲,這將執行提交處理器,並將結果顯示在特定位置

和示例一完全相同,僅將表單類替換如下:

<?php
/**
 * 演示表單AJAX操作
 */

namespace Drupal\yunke_help\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class YunkeForm extends FormBase
{
    public function getFormId()
    {
        return 'yunke_help_form';
    }

    public function buildForm(array $form, FormStateInterface $form_state)
    {
        $form['title'] = array(
            '#type'    => 'textfield',
            '#title'   => '標題,僅能輸入數字',
            '#pattern' => '[0-9]+',
        );

        $form['input'] = [
            '#type'  => 'textfield',
            '#title' => '輸入任意字符:',
            '#id'    => 'yunkeID',
            '#required' => TRUE,
        ];

        $form['actions']['#type'] = 'actions';
        $form['actions']['content_one'] = [ //用於顯示AJAX提交反饋
            '#type'       => 'html_tag',
            '#tag'        => 'div',
            '#attributes' => ['id' => 'content_one'],
        ];
        $form['actions']['submit'] = array(
            '#type'        => 'submit',
            '#value'       => 'AJAX提交',
            '#button_type' => 'primary',
            '#ajax'        => [
                'callback'        => '::yunkeTest',
                'event'           => 'click',
                'disable-refocus' => true,
                'wrapper'         => 'content_one',
                'method'          => 'html',
                'effect'          => 'fade',
                'speed'           => 1000,
                'prevent'         => 'click',//阻止非ajax提交,其實不需要這行,默認已阻止
                'progress'        => [
                    'type'    => 'throbber',
                    'message' => '表單正在提交中...',
                ],
            ],
        );
        return $form;
    }

    public function yunkeTest(array &$form, FormStateInterface $form_state)
    {
        /*
        //返回渲染數組,該方式將返回消息服務中的數據,以此顯示錯誤
        if($errors=$form_state->getErrors()){
            return ['#markup' => '表單已成功提交'];
        }else{
            return ['#markup' => '提交失敗,請檢查錯誤'];
        }
        */
        //如果不想反回消息數據,則使用以下代碼返回json響應:
        if ($errors = $form_state->getErrors()) {
            $message = ['提交失敗,請檢查錯誤:'];
            foreach ($errors as $error) {
                $message[] = $error;
            }

            //錯誤會沉積在消息系統中,體驗不好故刪除,但不要刪除非表單錯誤的消息
            $errorMessages = \Drupal::messenger()->deleteByType('error');
            foreach ($errors as $key => $error) {
                $errors[$key] = (string)$error;//可能是翻譯對象
            }
            foreach ($errorMessages as $key => $error) {
                if (!in_array((string)$error, $errors)) {
                    \Drupal::messenger()->addMessage($error, 'error');
                }
            }
        } else {
            $message = ['表單已成功提交'];
        }
        $response = new \Drupal\Core\Ajax\AjaxResponse();
        $html = ['#markup' => implode('<br>', $message)];
        $command = new \Drupal\Core\Ajax\InsertCommand(NULL, $html);
        $response->addCommand($command);
        return $response;
    }

    public function validateForm(array & $form, FormStateInterface $form_state)
    {
        if (empty($form_state->getValue('title'))) {
            $form_state->setErrorByName('title', '標題不能爲空');
        }
        file_put_contents('yunkeAJAX.txt', __CLASS__ . "驗證器\n", FILE_APPEND);
        //在根目錄寫入信息以便測試
    }

    public function submitForm(array & $form, FormStateInterface $form_state)
    {
        file_put_contents('yunkeAJAX.txt', __CLASS__ . "提交器\n", FILE_APPEND);
        $form_state->cleanValues();
        $d = print_r($form_state->getValues(), true);
        file_put_contents('yunkeAJAX.txt', "提交內容\n:{$d}\n", FILE_APPEND);
    }
}

說明:

該列演示了在提交元素上採用“#ajax”屬性設置表單ajax提交,這和示例一不同之處在於該列會執行提交處理器

 

示例六:

目的:在提交元素上採用類屬性“use-ajax-submit”進行提交與顯示

很遺憾,目前(V8.7,2019.7)系統在該功能上存在BUG,如下:

1、在該種情況下,系統本應自動添加“core/jquery.form”和“core/drupal.ajax”庫,但其並沒有,該bug已經被社區成員提交,現處於修復階段

2、在該種情況下,提交處理器需在表單狀態對象中設置一個ajax響應,這在成功提交的情況下將工作的很好,但是如果驗證失敗(此時不會執行提交處理器),控制器將返回表單數組,接着由AJAX主內容渲染器將其渲染成AJAX響應,由於該響應中,insert命令缺乏指向錯誤顯示元素的選擇器,因此頁面並不顯示錯誤,這雖然可以在驗證器中將表單數組的元素類型設置成“ajax”以在前端通過警告框進行錯誤提示,但顯然這並不優雅

 

由於以上bug尚未修復,建議目前以示例五代替

 

AJAX配置:

AJAX配置是前端系統所需的用來爲頁面元素設置一個AJAX行爲的信息(在下集原理篇中會有更深入的體會),在後端以數組形式存在,在前端以數據對象形式存在,通常通過JS配置設置機制傳遞到前端全局變量drupalSettings中,但有些情況爲了更加便捷,系統支持部分元素只需要設置少許屬性即可實現AJAX,此時不需要傳遞AJAX配置,典型的是設置了類屬性“use-ajax”的鏈接和設置了類屬性“use-ajax-submit”的表單按鈕,前端系統會爲它們自動產生AJAX配置並設置AJAX行爲。

從系統流程角度看,AJAX配置在系統中有三種存在形式(或存在位置):

元素“#ajax”屬性值:

也就是元素渲染數組的“#ajax”屬性值,需要注意的是並不是所有元素都能使用“#ajax”屬性,僅在渲染過程中能調用到以下方法的元素纔可以:

  \Drupal\Core\Render\Element\RenderElement::preRenderAjaxForm

這通常是表單元素,該方法會將“#ajax”屬性值處理成JS設置中的AJAX配置後傳遞到前端(準確說是傳遞到附屬物中)

JS設置值:

在後端這也稱爲位於渲染附屬物中,也就是渲染數組中以下項的值:

  $element ['#attached']['drupalSettings']['ajax']['元素ID']

渲染數組的$element ['#attached']['drupalSettings']用於給前端傳遞設置信息,位於這裏的AJAX配置稱爲標準AJAX配置,或最終AJAX配置,不會再被處理,將直接傳遞給前端,在前端位於以下全局變量中:

  drupalSettings.ajax.元素ID

注意:以JS設置值這種方式直接傳遞AJAX配置,看起來更加底層,但並不能完全代替表單元素的“#ajax”屬性值方式傳遞,主要原因在於回調參數並不通過前端傳遞,在內部系統會先找到觸發元素,再通過其:['#ajax']['callback']屬性找到回調,這種機制要求回調僅設置在“#ajax”屬性中

前端自動產生:

爲一些特殊元素設置AJAX行爲時,由前端自動產生,如前文提到的設置了類屬性“use-ajax”的鏈接和設置了類屬性“use-ajax-submit”的表單按鈕

 

AJAX配置項說明:

AJAX配置可用鍵名及其解釋如下(部分選項根據存在位置不同,可能會有所不同):

callback:

表單AJAX請求時服務器端的回調,僅用於表單元素,且僅用於表單元素的“#ajax”屬性中,在該屬性中是必須的,用在JS設置值的AJAX配置中無效(因爲該項並不通過前端傳遞),和設置提交處理器或驗證器方法一樣,如“::yunkeTest”,可以是任意有效php回調,按次序接收三個參數:&$form、$form_state和請求對象,可以用他們獲取用戶當前的輸入,回調應該返回渲染數組,字符串需用['#markup' => $markup]包裝成渲染數組,此時除返回值外,消息管理器(\Drupal::messenger())中的全部內容也會被返回;回調也可以返回json響應對象:

  \Drupal\Core\Ajax\AjaxResponse

此時不會自動返回消息管理器中的內容,但可以明確通過命令的方式添加。

注意:回調在表單流程之後執行,如果AJAX用在非提交元素中,在回調執行前,表單驗證器會執行,但驗證錯誤被鎮壓,提交處理器不會被執行,如果用在提交元素中,驗證器會執行,錯誤不會鎮壓,驗證通過時提交器已執行,提交器返回的響應被忽略,最後執行回調,響應以回調的返回值爲準

url:

AJAX請求地址,如果AJAX配置是在#ajax屬性中指定,那麼表明元素是表單元素,那麼該項可以省略,內部會採用當前表單地址,如果不省略的話,則必須是url對象(\Drupal\Core\Url),如果AJAX配置是在附屬物中指定,那麼該項是必須的,且必須是一個字符串值,在前端以此項作爲AJAX請求地址,並不關注callback

options:

僅當AJAX配置是在#ajax屬性中指定時纔有用,在url爲url對象時,用於url對象的選項參數,在附屬物中,AJAX配置的url項已經被轉變成字符串,此時該項已經不需要存在了

wrapper

在AJAX請求返回html內容時,用來放置內容的元素的id屬性值,將來會用“selector”代替,以便可使用任意選擇器來指定元素,目前只支持id,注意其值不要有“#”前綴

dialogType:

可選值爲dialog、modal,表示以這些方式之一顯示AJAX內容,優先級高於wrapper,在渲染數組的“#ajax”屬性中設置無效,因爲內部實際上據此包裝格式會有不同的主內容渲染器,而“#ajax”屬性僅支持AJAX主內容渲染器

method:

在使用wrapper 放置內容時,採用的jQuery放置方法,可選值有:replaceWith(替換整個id元素,這是默認值)、html(替換子內容)、append(在裏面尾部追加)、prepend(在裏面頭部追加)、before(在外部前面追加)、after(在外面後面追加)

effect:

在放置內容時,採用的jQuery動畫效果,可選值有:none (默認值,無效果)、slide(下拉顯示)、fade(慢慢淡出)

speed:

在使用放置動畫時的動畫速度,可選值有:slow(慢)、fast(快)、none(默認值,jQuery默認速度)或者一個以毫秒爲單位的數字

event:

在該元素上觸發AJAX的js事件(後稱AJAX事件),有默認值時是可選的,默認會依據表單元素的類型自動選擇,見下文,如果提供了值將以提供值爲準,如果沒有默認值則必須指定,不帶on前綴,如change、keyup、input等,當有多個時使用空格分隔,最終將傳遞給jquery的on方法,可帶名字空間

prevent:

當觸發AJAX的js事件發生時要阻止的其他事件,比如觸發事件是mousedown,此時你可能會想阻止click事件,當有多個時使用空格分隔,最終將傳遞給jquery的on方法,可帶名字空間,事件傳播和默認動作都會被阻止;可與AJAX事件相同,不會影響AJAX,僅會阻止該事件的傳播和默認動作,但這沒有必要,因爲AJAX行爲默認會阻止事件的傳播和默認動作

progress:

用於配置進度指示器,當不需要顯示進度指示時,可以設置爲false,一個數組值,各子鍵爲:

type:進度指示器的類型,可選值有:throbber(在元素後邊顯示一個轉圈的等待動畫圖片,默認值)、bar(結合其他選項以進度條方式顯示)、fullscreen(全屏居中顯示一個等待動畫圖標)、false(禁用指示器,布爾值)

message:提示消息,字符串值,如“請稍後…”,應該是被翻譯過的,默認爲Drupal.t('Please wait...')

url:使用進度條時,獲取進度數據的url,字符串值,在#ajax屬性中也可以是url對象

method:請求進度條更新url時使用的http方法,get或post,默認爲get

interval:使用進度條時,多長時間更新一次,單位毫秒,默認1500毫秒

當數組中僅有type時,該項可簡寫爲type表示的字符串值

disable-refocus:

布爾值,指示ajax調用後,是否禁止重新獲得焦點,默認爲false,也就是會重新獲得焦點,很多時候需要被設置爲true,否則焦點會被反覆拉回到元素導致用戶無法使用

keypress:

布爾值,是否在元素上監聽鍵盤事件,以便可以通過按壓空格或回車鍵觸發AJAX事件,默認爲true,將在元素上監聽“keypress”事件,注意有四種類型的表單元素:text、textarea、tel、number即便設置了該項,也不會通過空格觸發AJAX事件,但回車可以

submit:

額外提交到服務器的數據,一個數組值,鍵名爲name,鍵值爲value;前端系統默認的並不會設置是哪一個元素觸發了ajax請求(也可以理解成不會設置是哪個元素觸發了表單AJAX提交),如果AJAX配置是在#ajax屬性中指定,爲了告訴後端觸發元素,系統在該項添加了以下變量:

_triggering_element_name:觸發元素名

_triggering_element_value:觸發元素值,可選

如果AJAX配置是在附屬物中指定,需要用戶來設定觸發元素,如果沒有設置,那麼後端在不知道觸發元素的情況,會以第一個按鈕元素當做觸發元素

trigger_as:

是一個數組,用於指定一個表單提交元素(讓後端知道是哪個元素觸發了表單提交),鍵名name爲觸發元素名,value爲觸發元素值,該項是可選的,默認以本元素的name和value作爲觸發元素名和值,僅在#ajax屬性中有效,該項在附屬物中的AJAX配置裏會被刪除(信息已經提取到submit項中)

setClick:

布爾值,僅用於表單提交元素,如提交按鈕,指示將當前元素當做觸發表單提交的元素,並傳遞其名值到服務器,在內部普通表單元素該項默認爲false,使用“.use-ajax-submit”類的表單元素默認爲true ,因爲普通表單元素本就會被傳遞,且“.use-ajax-submit”類的表單元素會自動設置爲true,因此該項用戶無需理會,這裏列出僅供程序研究參考,注:不要將該項和trigger_as項混淆,任何表單元素的AJAX操作都會提交整個表單,trigger_as項常用在當前元素爲非提交元素時,指定提交元素,而該項僅用於提交元素,如按鈕,指示是否將本元素當做提交元素,當發生衝突時,該項優先級高於trigger_as項。

 

AJAX配置默認事件:

在沒有指定事件名時,以下元素類型(渲染數組類型)將採用默認事件:

submit、button、image_button

默認事件名:mousedown,同時在沒有設置阻止事情的情況下阻止click事件

password、textfield、number、tel、textarea

默認事件名:blur

radio、checkbox、select、date

默認事件名:change

link

默認事件名:click

注意:除以上這些元素類型外,其他元素類型必須設置事件名,否則不被設置ajax行爲

 

官網參考文檔:

AJAX API概述:

https://api.drupal.org/api/drupal/core!core.api.php/group/ajax/

創建Ajax菜單鏈接:

https://www.drupal.org/docs/8/api/menu-api/making-ajax-menu-links

AJAX表單示例:

https://www.drupal.org/docs/8/api/javascript-api/ajax-forms

命令:

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Ajax%21CommandInterface.php/interface/implements/CommandInterface

 

補充:

1、如果在具備#ajax屬性的元素上設置#ajax_processed,那麼不論何值(NULL除外),只要設置了,那麼就不會被附加AJAX行爲,相當於沒有給元素添加#ajax屬性,調試時比較有用,被附加#ajax的元素處理後,會附加該屬性,值爲true。

2、在AJAX API中表單元素的AJAX操作總是提交整個表單值到後端,所有AJAX均以POST方式發起

 

我是雲客,【雲遊天下,做客四方】,聯繫方式見主頁,歡迎轉載,但須註明出處

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章