我有一个模块,当单击链接时,该模块通过ajax更新节点。
该链接是一个切换,它应在第一次单击时将节点更新为值1,然后在随后的单击中将节点更新为0,以此类推。就像打开/关闭某些内容一样。
下面的代码在页面加载后的第一次点击上有效,但在随后的点击上无效。我相信每次单击后都必须调用/触发Drupal.attachBehaviors,但是我不知道该怎么做。
模块
function mymodule_menu() { $items['mypath/%/%/ajax'] = array( 'title' => 'My title', 'page callback' => 'mymodule_ajax_callback', 'page arguments' => array(1,2), 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); ... } function mymodule_ajax_callback($id, $status) { //Validation[...] //Node Update using $id as the nid and $status as the field value[...] // Define a new array to hold our AJAX commands. $ajax_commands = array(); // Create a new AJAX command that replaces the #div. $replacedivid = '#status'.$id; $replacestring = '<div id="status'.$id.'"><a data-url="'.base_path().'mypath/'.$id.'/'.$new_status.'/ajax" title="This item is marked as '.$status_text.'" id="statuslink'.$id.'" class="midui">'.$status_text.'</a></div>'; $ajax_commands[] = ajax_command_replace($replacedivid, $replacestring); return drupal_json_output($ajax_commands); }
Java脚本
(function ($) { Drupal.behaviors.mymodule = { attach: function(context, settings) { var $uilink = $('.midui'); //find all links for (var i=0;i<$uilink.length;i++) { //Loop var $link = $('#' + $uilink[i].id); if (!$link.hasClass("middone")) { new Drupal.ajax('#' + $uilink[i].id, $link, { url: $link.attr('data-url'), effect: 'fade', settings: {}, progress: { type: 'throbber' }, event: 'click tap' }); $link.addClass("middone"); //add class when we're done } } } } })(jQuery);
到目前为止我尝试过的是:
(a)ajax_command_invoke(NULL, 'mymodule');
在$ ajax_commands数组中加上一个$.fn.mymodule
函数
(b)添加$('body').ajaxSuccess(Drupal.attachBehaviors);
到我的javascript中。ajaxComplete也尝试过。在文件上也尝试过。
(c)创建一个自定义命令,如下所示:http://www.jaypan.com/tutorial/calling-function-after-ajax-event-drupal-7
注意:我知道这只是在每次单击以“ ajaxify”要插入/修改的新html之后触发attachBehaviors的问题。如果我单击该链接,然后在控制台中键入Drupal.attachBehaviors(),则该链接将由我的JavaScript再次处理,如添加的“ middone”类所证明,并且可以再次单击该链接。
注意:同样有趣的是,如果我将其保留为$ajax_commands
空并在回调函数的末尾将其返回(空数组),则该链接将在第一次和随后的单击中保持可单击状态。它将具有我要寻找的功能(切换)。但是,由于每次单击后都不会对html进行更改,因此用户无法知道切换是打开还是关闭。
任何指针将不胜感激。
================================================== =====
部分答案:
Drupal ajax.js成功函数仅重新附加表单的行为(我认为?)
if (this.form) {
var settings = this.settings || Drupal.settings;
Drupal.attachBehaviors(this.form, settings);
}
所以我决定破解我所有的ajax对象的成功功能。
现在,Javascript变为
(function ($) {
Drupal.behaviors.mymodule = {
attach: function(context, settings) {
var $uilink = $('.midui'); //find all links
for (var i=0;i<$uilink.length;i++) { //Loop
var $link = $('#' + $uilink[i].id);
if (!$link.hasClass("middone")) {
myAjax = new Drupal.ajax('#' + $uilink[i].id, $link, {
url: $link.attr('data-url'),
effect: 'fade',
settings: {},
progress: {
type: 'throbber'
},
event: 'click tap'
});
myAjax.options.success = function (response, status) {
//Trigger Attach Behaviors
setTimeout(function(){Drupal.attachBehaviors($(myAjax.selector))}, 0);
// Sanity check for browser support (object expected).
// When using iFrame uploads, responses must be returned as a string.
if (typeof response == 'string') {
response = $.parseJSON(response);
}
return myAjax.success(response, status);
}
$link.addClass("middone"); //add class when we're done
}
}
}
}
})(jQuery);
成功函数是ajax.js中默认值的复制粘贴,并添加了用于重新附加行为的行。由于某种原因,Drupal.attachBehaviors
必须在计时器内。我不能仅仅因为一个我会忽略的原因而拥有它。
如果有人可以找到一个更优雅的解决方案和/或解释计时器的奇怪之处,我将把这个问题留给少数人解决。
非常感谢