首页 > 解决方案 > TypeError:将 .done 链接到 ajax 包装函数时,e 未定义

问题描述

我创建了一个小型 ajax 函数包装器来启动$.ajax请求。
它可以工作,但是当尝试在.done, .failor中添加一个函数时.always,我收到了这个错误:TypeError: e is undefined.

这是我的 javascrip/jquery ajax 代码:

var $ajaxScript = 'scripts/ajax.php';  //  controller-script that handles all ajax request
/**
 *  ajax wrapper()
 *  $_POST array with form posts
 */
function submitAjax($_POST){
    ajaxObj = $.ajax({url:$ajaxScript, data:$_POST, type:'POST', dataType:'json' });
    return ajaxObj;
}

因为所有的 ajax 表单提交都是通过 发送的ajax.php,并且这些请求的返回数据响应总是设置为 json,我认为这将是一个方便的方法。
这使我能够创建一种快速的方法来执行“默认”ajax 请求,只需将类添加ajax到表单中即可。

$(function(){
    $("form.ajax").submit(function(e){
        e.preventDefault();
        submitAjax($(this).serialize())
        .done(function(data,statusText,jqXHR){
            $(this).prepend('<div class="notice"><p class="icon">'+data['msg']+'</p></div>');  //  *--  this triggers a "TypeError"
            console.log('done : '+statusText);  //  <--  this alone doesn't throw any error
        })
        .fail(function(){
            console.log('fail');
        })
        .always(function(){
            console.log('always');
        });
    });
});

如果我需要以另一种方式处理 ajax 请求,我可以通过为它创建一个新函数来实现:

$(function(){
$("#updRecipe").submit(function(e){
    e.preventDefault();
    /* do stuff before */
    var $Ajax = submitAjax($(this).serialize());
    /* do some more stuff */
    Ajax.done(function(){

    });
    /*  ...  do stuff at the end  ...  */
});
});

这是我使用的表单布局:
通过添加 class ajax,表单被视为使用顶部代码的 ajax 请求。
隐藏字段“load-ajax”用于ajax.php确定请求使用什么脚本。
-button的名称submit是脚本中要执行的部分或部分的标识符。

<form class="ajax">
    <input type="hidden" name="load-ajax" value="Recipe">
    <input type="text" name="name" value="<?=$get_recipe['name']?>">
    <input type="submit" name="submit__updName" value="Oppdater oppskrift">
</form>

当我一无所有或仅console.log()在方法内部时,代码就可以工作。但是当我尝试添加其他 jquery 函数时它失败了。

TypeError: e is undefined,并且代码未正确执行。或者,没有正确执行返回给用户的输出。

我在这里做错了什么?
仅当在其中一种方法之外添加函数时才会发生错误...

标签: jquery

解决方案


this调用的内部.done回调$.ajax指的是 jqXHR,它是一个Ajax 事件- 基本上是 XHR 调用本身的包装器。

因此,它不再是<form>(或者,在某些情况下 - 不是你的 - ,<button启动自定义提交功能的)。

因此,如果你想<form>在回调中引用 ,你必须在选择的变量中放置对它的引用:

$("form.ajax").submit(function(e){
  e.preventDefault();
  let $form = $(this);

  /* do stuff before
   * `this` is <form> 
   */

   var $Ajax = submitAjax($(this).serialize());
   Ajax.done(function(){

     /* in here `this` is third param of the function, 
      * the jqXHR event 
      */

      $form.prepend('...');
    });

  /*  ...  do stuff at the end  
   *  `this` is still <form>  
   */
});


推荐阅读