jquery.ui.autocomplete 向程式要資料,資料為何沒有傳到頁面上?

摘要:jquery.ui.autocomplete 向遠端要資料時會有問題

 

最近發生autocomplete 向遠端要資料時,資料雖有回傳,卻無法傳到頁面上的問題。

後來研究出來,原因如下:

除了使用automplete之外,檢查專案裡面有沒有引用jquery.validate.js ?

如果有的話  看一下 jquery.validate.js 是哪一版的  
 
如果是1.6版左右  那就是 jquery.validate.js 所引發的問題
 
autocomplete 是使用 ajax 方式向後端要資料,就是下面這段程式碼,在260行左右。
 
self.xhr = $.ajax({
    url: url,
    data: request,
    dataType: "json",
    autocompleteRequest: ++requestIndex,
    success: function (data, status) {
        if (this.autocompleteRequest === requestIndex) {
            response(data);
        }
    },
    error: function () {
        if (this.autocompleteRequest === requestIndex) {
            response([]);
        }
    }
但是當他在執行這段程式的時候,卻會跳去執行  jquery.validate.js 的這段程式碼,在1096行左右。
 
;(function ($) {
    var ajax = $.ajax;
    var pendingRequests = {};
    $.ajax = function (settings) {
        // create settings for compatibility with ajaxSetup
        settings = $.extend(settings, $.extend({}, $.ajaxSettings, settings));
        var port = settings.port;
        if (settings.mode == "abort") {
            if (pendingRequests[port]) {
                pendingRequests[port].abort();
            }
            return (pendingRequests[port] = ajax.apply(this, arguments));
        }
        return ajax.apply(this, arguments);
    };
})(jQuery);
 
因為這個原因,造成 autocomplete 每次向後端要資料時,資料就算有要到,也有成功回傳
 
但 autcomplete 卻不會跳到 success ,而是跳到 error 的部分,所以無法把資料傳到頁面上。
 
 
解決方式有2種:
 
1. 下載最新版的 jquery.validate.js,目前最新版是 1.8.1 版。
 
2. 手動修改 jquery.validate.js , 把上面 validate 的程式碼,改成下面這段即可。
 
;(function ($) {
    var pendingRequests = {};
    if ($.ajaxPrefilter) {
        $.ajaxPrefilter(function (settings, original, jqXHR) {
            var port = settings.port;
            if (settings.mode == "abort") {
                if (pendingRequests[port]) {
                    pendingRequests[port].abort();
                }
                pendingRequests[port] = jqXHR;
            }
        });
    } else {
        var ajax = $.ajax;
        $.ajax = function (settings) {
            // create settings for compatibility with ajaxSetup
            settings = $.extend(settings, $.extend({}, $.ajaxSettings, settings));
            var port = settings.port;
            if (settings.mode == "abort") {
                if (pendingRequests[port]) {
                    pendingRequests[port].abort();
                }
                return (pendingRequests[port] = ajax.apply(this, arguments));
            }
            return ajax.apply(this, arguments);
        };
    }
})(jQuery);