Drupal7 ajax 应用研究以及invoke方法BUG解决

Events happening in the community are now at Drupal community events on www.drupal.org.
Posted by GloolsGuan on January 16, 2013 at 5:32am

Drupal AJAX 系统表单处理流程

  1. 设置

    DRUPAL7 AJAX form 的作用域通常为:

    1. 按钮, 例如各类 button, 和 submit等,可以响应事件。
    2. FORM 各类元素,包含input, textarea, options 等,都可以相应AJAX事件。

    AJAX form 的有效性设置


    $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Submit',
    '#ajax' => array(
    'event' => 'click',
    'callback' => 'sample_ajax_render',
    'method' => 'replace'
    )
    );

    AJAX所请求path 需要设置 'delivery callback' => 'ajax_deliver' 如下:

    function SAMPLE_menu(){
    return array(
    'register/%' => array(
    'title' => t('Register'),
    'type' => MENU_CALLBACK,
    'page callback' => 'frontend_register',
    'access arguments' => array('access content'),
    'file' => 'register.page.inc',
    'delivery callback' => 'ajax_deliver'
    )
    );
    }
    注: 该设置标明,该页面的输出需要由ajax_deliver控制,通常输出ajax commands(@see includes/ajax.inc)格式的json字符串,
    并会附加一些其它系统默认操作。

    AJAX元素所设置的callback函数格式:

    function sample_ajax_render(&$form, &$form_state){

    $commands = array();
    $commands[] = ajax_command_[REPLACE](....);
    /*
     D7系统内置支持的AJAX命令全部在 includes/ajax.inc 文件中。这里ajax_command_? 设置,是由服务器端设置客户端AJAX响应命令。
     也就是说,这里设置的命令客户端ajax.js 会有响应的操作。比如置换 replace, 附加 append等等。
     注意,这里ajax_command_invoke,默认只支持jQuery内建的方法,如果是你自己开发的方法,通过如下代码加载到jQuery:
     var a=function(){
     this.b = 'hello,world'
     };
     //-- 这里只是申请一个jquery名字空间,并不是实际的设置。
     jQuery.fn.extend(jQuery, a);
     //-- 下面的语句会使jQuery对象化a函数,例如, 在如下语句执行后, 你可以通过 alert(a.b); 得到 "hello,world"输出结果。
     jQuery.a = a;
     回到D7 ajax.js, 如上所述,此时如果你在服务器端:
     ajax_command_invoke(NULL, 'a', array(...));
     ajax.js 并不能真的调用 a 对象,但是如果这里的 a 是 'addClass'等 jQuery内建对象,则可以正常使用,解决的办法是修改ajax.js源码如下:
     //-- Fixed by GloolsGuan@glools.com at 2013年1月6日
     //-- original drupal7 ajax.js code --
     $element[response.method].apply($element, response.arguments);
     //-----------------------------------
     //-- new code for fixing personal jQuery object invoke
     if (undefined==$element[response.method]) {
     $[response.method](response.arguments);
     }else{
     $element[response.method].apply($element, response.arguments);
     }
     //------------------------------------
     将以上原始ajax.js 604行左右, 代码换成新代码即可。
     invoke: function (ajax, response, status);
    */
    return array(
     '#type' => 'ajax',
     '#commands' => $ajaxCommands
    );
    

    }

  2. AJAX form的处理流程
    -- PHP 端设置 --

    1. drupal系统根据表单AJAX项设置,会自动加载ajax.inc 文件,包含ajax.js程序。
      -- DRUPAL系统自动处理部分 --
    2. drupal系统会修改表单,在添加有 #ajax项目的FORM 元素上,添加 HTML 节点属性
      class='ajax-processed', 以此标明该节点相应需要AJAX处理。
      -- 客户端相应部分--
    3. 当用户点击或触发AJAX标注的FORM元素时,一个AJAX请求会由ajax.js 建立,并根据设置请求服务器响应。
      -- 服务器端相应部分 --
    4. 服务器接收到AJAX请求依次处理顺序如下:
      1. 处理表单 即 [FORM_ID]_validate, [FORM_ID]_submit等,会先执行。
      2. 调用sample_ajax_render,处理表单输出结果。
        -- D7系统操作部分
      3. 处理sample_ajax_render返回值,并附加系统AJAX相关参数生成JSON字符串,由 ajax_deliver负责最终输出结果。
        换句话说,在sample_ajax_render 中,如果你 直接 print 'hello,world'; AJAX客户端也可以接收,并且服务器端正常运行。
        但是客户端AJAX表示崩溃,因为无法识别数据,当然如果客户端操作你自己写的,另当别论。
    5. 客户端ajax.js根据服务器端返回json格式的drupal7 ajax 命令,依次执行。
    6. 一次AJAX请求流程结束。
  3. 自己调用Drupal.ajax js 对象可以的,注意事项如下,且意义不大:

    1. ajaxInstance = new Drupal.ajax(base, element, element_settings);
    2. base 参数是form表单父级节点。
      element 是当前操作的html元素对象。
      element_settings 是ajax请求相关参数设置,具体参考 ajax.js 这里ajax.js说明很不清楚,得自己研究代码。
Categories: ,

Comments

剖析得很好,其实有drupal经验的,看一下ajax

Posted by lcnphp on January 16, 2013 at 5:39am

剖析得很好,其实有drupal经验的,看一下ajax comment http://drupal.org/project/ajax_comments模块的代码就完全明白了

剖析得很好,其实有drupal经验的,看一下ajax

Posted by lcnphp on January 16, 2013 at 5:39am

剖析得很好,其实有drupal经验的,看一下ajax comment http://drupal.org/project/ajax_comments模块的代码就完全明白了

这个模块没有用过,大概扫了一眼,似乎和D7内核AJAX框架有些冲突,不过说实话,drupal7的这一套ajax框架还是很强的。缺点在于DEBUG,不是很方便,同时扩展有些不易。

The creator of GLOOLS.

它就是用ajax_command_*

Posted by lcnphp on January 17, 2013 at 2:28am

它就是用ajax_command_*

话说ajax的debug, 你们有什么更好的方法?

Posted by rogical on January 17, 2013 at 2:49am

话说ajax的debug, 你们有什么更好的方法? 很多时候dpm是无法输出了,还容易破坏json结构。
用watchdog, 大数组大对象打印的时候又不利于观看。

watchdog('debug', ' '.

Posted by lcnphp on January 17, 2013 at 3:02am

watchdog('debug', '

'. print_r($form_state, 1) .'

');

在Glools-Drupal框架中,有一个debug模块,

Posted by GloolsGuan on January 17, 2013 at 5:15am

在Glools-Drupal框架中,有一个debug模块,专门负责服务器端debug, 通过命令窗口,及时获取调试信息。 在ajax 的客户端JS部分有一个类似的TEST.js 程序也是用来做客户端调试的,可以输出一个对象。

基于服务器端的DEBUG目录结构要求
www.domain.com/
webroot/drupal code
debug/???.txt

使用命令 tail -f debug/???.txt -n 100 可以及时获取测试信息。

The creator of GLOOLS.

< pre> 居然被过滤了

Posted by lcnphp on January 17, 2013 at 3:03am

< pre> 居然被过滤了

用watchdog加上pre 也打印出 树状点击折叠的

Posted by rogical on January 17, 2013 at 5:42am

(削除) 用watchdog加上pre 也打印出 树状点击折叠的 dpm效果吧 (削除ここまで)

用watchdog加上pre 也打印不出 树状点击折叠的 dpm效果吧

达不到dom那么好看,起码舒服很多了

Posted by lcnphp on January 17, 2013 at 5:44am

达不到dom那么好看,起码舒服很多了

Form 元素使用D7 ajax

Posted by hooface on January 17, 2013 at 4:55am

Form 元素使用D7 ajax 很方便,如果不了解JS,可以不用写行 JS 代码,但扩展比较麻烦一些,虽然提供了一些 hook,要熟悉一下也是需要时间的。
对于非表单元素,我喜欢直接使用 JQuery.ajax,流程也好控制。
有兴趣的可以看看 http://dev.twippo.com 这个网站,大量使用了 ajax ,但需要注册一下用户才可体验某些功能。

D7, 的AJAX

Posted by GloolsGuan on January 17, 2013 at 5:17am

D7, 的AJAX 非表单部分操作,和客户自定义JS,引用却有问题,这就是为什么发布这个帖子,并提供了修复方法的原因。不过修复后,要求自己开发的js组件,必须注册为jQuery的对象。否则还是无效。

The creator of GLOOLS.

我在项目中没有遇到什么问题

Posted by hooface on January 18, 2013 at 11:37am

我在项目中没有遇到什么问题。
你指的"引用却有问题"能具体点吗?
另外你说的"自己开发的js组件,必须注册为jQuery的对象",这可能是名字空间引起的,为了防止客户的 js 与核心或其他 js库 冲突,Drupal 7 将 jQuery 作为一个名字空间,具体可以看看这篇文档:http://drupal.org/node/756722

DrupalHK

Group categories

HKDUG Vocabulary

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds:

AltStyle によって変換されたページ (->オリジナル) /