121. 系统AJAX(四):命令

drupal AJAX api中,AJAX请求获取的数据均是以“命令”方式在页面中进行更新,命令由两部分核心内容组成:执行更新的JS函数、函数操作所需的数据(参数),实现命令概念需要前后端配合。

 

命令概述:

在前端:

一条命令就是一个对象,称为命令对象,是一个纯js数据对象,该对象必须存在属性:command,她的值是命令名,命令名是一个js函数的函数名,该函数称为命令函数,必须存在于以下前端全局变量中:

  Drupal.AjaxCommands.prototype

如果不存在,那么命令是无效的,命令对象的其他属性属于命令携带的数据,根据命令不同而不同。

所有命令函数均按序接受三个参数:AJAX对象、命令对象、状态信息,AJAX结果动作由命令函数完成

在后端:

每一个AJAX命令由一个类表示,这些类均需要实现以下接口:

  \Drupal\Core\Ajax\CommandInterface

该接口仅有一个render()方法,用于返回一个命令数组,该数组将被序列化成json字符串,传递到前端后就是前文所述的命令对象

同样的,命令也可以传递附属物(资源库、配置变量),这样的命令需要实现以下接口:

  \Drupal\Core\Ajax\CommandWithAttachedAssetsInterface

在实现上可以直接使用以下特征:

   \Drupal\Core\Ajax\CommandWithAttachedAssetsTrait

命令由以下AJAX响应对象传递到前端:

  \Drupal\Core\Ajax\AjaxResponse

一次AJAX请求可以传递多个命令,通过该AJAX响应对象的以下方法添加:

  public function addCommand(CommandInterface $command, $prepend = FALSE)

参数$command为命令对象,添加顺序就是前端执行命令的顺序,如果需要后添加但先执行,那么需要将参数$prepend设置为true

如果后端传递的命令,在前端不支持将是没有用的,接下来我们看一看系统默认提供了哪些命令。

 

插入命令insert

命令名:insert,用于向页面插入html内容

在前端:

前端方法:Drupal.AjaxCommands.prototype.insert(ajax, response)

(前文已讲了所有js命令函数按序接收三个参数:AJAX对象、命令对象、状态信息,因此此处及下文不再解释命令函数的参数含义)

响应对象除包含command属性外(值为insert,下文所有命令均包含该属性,仅值不同,将不再赘述),还有以下属性:

selector可选,执行插入操作的目标元素的jquery选择器,字符串值,含义等同AJAX配置中的wrapper项,但优先级更高

method可选,插入所用的方法,含义等同AJAX配置中的method项,但优先级更高

effect可选,插入或替换动画效果,含义等同AJAX配置中的effect项,但优先级更高

speed可选,插入或替换动画速度,含义等同AJAX配置中的speed项,但优先级更高

data必选,字符串值,通常是要插入的html片段,里面如包含JS,会被执行,当使用empty方法时该项被忽视,此时可以是空字符串

settings可选,一个设置对象,当成功插入DOM后,用于对插入的各根元素执行Drupal.attachBehaviors,这允许其他组件为其添加js事件,当有元素移除时(插入是替换操作),用于Drupal.detachBehaviors方法;优先级最高,其次是AJAX配置中的settings项,最后是drupalSettings

 

在后端:

插入命令类:\Drupal\Core\Ajax\InsertCommand

使用示例:

        $ajaxResponse = new \Drupal\Core\Ajax\AjaxResponse();
        $html = ['#markup' => '示例'];
        $command = new \Drupal\Core\Ajax\InsertCommand(NULL, $html);
        $ajaxResponse->addCommand($command);
        return $ajaxResponse;

该命令的构造函数接收三个参数:

$selector:执行插入操作的目标元素的jquery选择器,字符串值,见前文

$content:可以是一个渲染数组,或html字符串片段,当是渲染数组时附属物会自动处理

$settingsjs设置数组,见前文的js设置对象

 

该命令无法直接指定插入方法,当客户端Ajax对象指定了方法时,这样很好,如需指定方法用以下类代替:

在外部前面追加插入:

  \Drupal\Core\Ajax\BeforeCommand

在外面后面追加插入:

  \Drupal\Core\Ajax\AfterCommand

在里面头部追加插入:

  \Drupal\Core\Ajax\PrependCommand

在里面尾部追加插入:

  \Drupal\Core\Ajax\AppendCommand

整个元素替换插入:

  \Drupal\Core\Ajax\ReplaceCommand

替换全部子内容插入:

  \Drupal\Core\Ajax\HtmlCommand

以上这些类全部继承插入类,实例化方法也一样,仅仅方法不同而已

 

移除命令remove

命令名:remove,用于移除页面元素

在前端:

前端方法:Drupal.AjaxCommands.prototype.remove(ajax, response, status);

响应对象必须包含selector属性,字符串值,jquery选择器,指示要移除的元素,否则命令无效,可选的传递settings属性,用于移除时,对各元素执行Drupal.detachBehaviors方法

在后端:

命令类:\Drupal\Core\Ajax\RemoveCommand

构造函数仅接收一个字符串值的jquery选择器做参数

 

标记改变命令changed

命令名:changed,用于标记一个元素被更改,而不是更改一个元素

在前端:

前端方法:Drupal.AjaxCommands.prototype.changed(ajax, response, status)

响应对象必须包含selector属性,字符串值,jquery选择器,指示哪个元素要被标记为已更改,否则命令无效,可选的传递asterisk属性,也是一个jquery选择器,应是selector所指元素的子元素,如果指定了将在该元素内追加一个星号标记

在后端:

命令类:\Drupal\Core\Ajax\ChangedCommand

构造函数接收两个参数:

$selector:必选,一个字符串值的jquery选择器

$asterisk:可选,一个字符串值的jquery选择器

 

警告弹框命令alert

命令名:alert,用于通过alert方法弹出警告框

在前端:

前端方法:Drupal.AjaxCommands.prototype.alert(ajax, response, status);

响应对象包含两个属性,text弹框内容,title弹框标题(bug:该参数是无意义的)

在后端:

命令类:\Drupal\Core\Ajax\AlertCommand

构造函数仅接收一个字符串值参数做弹框内容

 

无障碍消息通知命令announce

命令名:announce,用于向残障设备发送消息通知,详见前端Drupal.announce方法

在前端:

前端方法:Drupal.AjaxCommands.prototype.announce(ajax, response);

响应对象包含两个属性:

text:被通知的消息

priority:可选值,优先级

在后端:

命令类:\Drupal\Core\Ajax\AnnounceCommand

构造函数按序参数为$text, $priority = NULL,该命令会加载核心库:core/drupal.announce

 

重定向页面命令redirect

命令名:redirect,用于将页面跳转到指定的url地址

在前端:

前端方法:Drupal.AjaxCommands.prototype.redirect(ajax, response, status);

响应对象包含一个属性,url重定向地址,将赋值给window.location以实现重定向

在后端:

命令类:\Drupal\Core\Ajax\RedirectCommand

构造函数仅接收一个字符串值的url参数做重定向

 

CSS样式修改命令css

命令名:css,用于执行jquerycss方法修改元素样式

在前端:

前端方法:Drupal.AjaxCommands.prototype.css(ajax, response, status);

响应对象包含两个属性:

selector:要运用样式的元素的选择器

argumentjquerycss方法的参数

在后端:

命令类:\Drupal\Core\Ajax\CssCommand

构造函数按序参数为:$selector, array $css = []

 

js配置命令settings

命令名:settings,用于为其他命令设置配置对象或修改全局配置对象drupalSettings

在前端:

前端方法:Drupal.AjaxCommands.prototype.settings(ajax, response, status);

响应对象包含两个属性:

settings:一个配置对象

merge:布尔值,如果为true,那么将把settings配置对象深度递归合并到全局配置对象drupalSettings中,否则将把配置对象赋值给Ajax对象的settings属性,以供该Ajax对象上的其他命令使用,比如插入命令就用到了该配置对象(这使得在AJAX请求后可以设置新的AJAX行为)。

该命令还会将已经失效的AJAX配置从全局配置:drupalSettings.ajax中删除

在后端:

命令类:\Drupal\Core\Ajax\SettingsCommand

构造函数按序参数为:array $settings, $merge = FALSE

 

数据设置命令data

命令名:data,用于通过jquerydata方法为元素设置数据

在前端:

前端方法:Drupal.AjaxCommands.prototype.data(ajax, response, status);

响应对象包含三个属性:

selector:被附加数据的元素的jquery选择器

name:数据键名

value:数据键值

在后端:

命令类:\Drupal\Core\Ajax\DataCommand

构造函数按序参数为:$selector, $name, $value

 

jquery方法执行命令invoke

命令名:invoke,用于在jquery对象上执行一个jquery方法

在前端:

前端方法:Drupal.AjaxCommands.prototype.invoke(ajax, response, status);

响应对象包含三个属性:

selector:选择器字符串,将在该选择器产生的jquery对象上执行jquery方法

method:任意有效的jquery方法

args:方法所需的参数,是一个数据对象,将通过“”运算符展开后传递给方法

在后端:

命令类:\Drupal\Core\Ajax\InvokeCommand

构造函数按序参数为:$selector, $method, array $arguments = []

 

重构表命令restripe

命令名:restripe,用于给表中的行重新设置奇偶数类名(oddeven

在前端:

前端方法:Drupal.AjaxCommands.prototype.restripe(ajax, response, status);

响应对象包含一个属性:

selector:选择器字符串,将作用在该选择器指定的元素的子元素上

在后端:

命令类:\Drupal\Core\Ajax\RestripeCommand

构造函数仅接收一个字符串值的jquery选择器参数

 

更新表单id命令update_build_id

命令名:update_build_id,用于更新表单id的值

在前端:

前端方法:Drupal.AjaxCommands.prototype.update_build_id(ajax, response, status);

响应对象包含两个属性:

old:旧表单id

new:新表单id

在后端:

命令类:\Drupal\Core\Ajax\UpdateBuildIdCommand

构造函数按序参数为:$old, $new

 

CSS文件或标签加载命令add_css

命令名:add_css,用于加载一个css样式表文件或<style>标签到页面,这不同于“css”命令,后者仅修改一个样式属性

在前端:

前端方法:Drupal.AjaxCommands.prototype.add_css(ajax, response, status);

响应对象包含一个属性:

data:字符串值的html片段,可以是一个加载css文件的link标签,也可以是一个<style>标签,将通过prepend方法(里面、前面)追加到head标签中,预追加操作意味着添加的样式优先级是很低的,样式标签中的@import将得到处理

在后端:

命令类:\Drupal\Core\Ajax\AddCssCommand

构造函数仅接收一个字符串值的$styles参数,含义同data

 

自定义命令:

如果系统默认提供的命令不能满足需求,那么可以自定义,一个命令需要前后端配合执行,缺一不可,因此需要在前后端均进行扩展:

在前端:

向以下全局变量添加命令函数:

Drupal.AjaxCommands.prototype

函数名必须和命令名相同,由此也可看出命令名必须满足js函数名要求,接收以下参数:

AJAX对象、命令对象、状态信息

该函数在前端执行js动作,通过命令对象的属性获取后端传递的数据

在后端:

实现一个命令类,必须实现以下接口:

  \Drupal\Core\Ajax\CommandInterface

类名随意,最佳实践是以命令名的驼峰命名法加“Command”做后缀,在方法render()中返回一个数组,其中必须存在键名:command,其对应的键值为命令名,可选的传递其他代表命令所需数据的数组元素(注意:这不是js命令函数的参数),在前端该数组键名将作为命令对象的属性名

如果命令有附属物需要处理,还应实现以下接口:

  \Drupal\Core\Ajax\CommandWithAttachedAssetsInterface

此时可以使用以下特征:

  \Drupal\Core\Ajax\CommandWithAttachedAssetsTrait

 

补充:

1、后端提供了基础命令类:\Drupal\Core\Ajax\BaseCommand,可以指定命令名和数据,有时会很有用

2、关于dialogmodal主内容渲染器、相关AJAX命令、前端实现将在专门的主题中讲解

 

本书共161小节。


目前全部收费内容共295.00元。购买全部

评论 (0)