Краткий синтаксис для автозаполнения jquery-ui при вызове веб-службы WCF - PullRequest
0 голосов
/ 24 января 2012

Этот пример использования автозаполнения jquery-ui с удаленным веб-сервисом имеет приятный лаконичный синтаксис:

$( "#birds" ).autocomplete({
source: "search.php",
minLength: 2
});

Здесь search.php возвращает массив следующим образом:

[ 
    { "id": "Passer domesticus", "label": "House Sparrow", "value": "House Sparrow" },
    ...
]

Я хочу использовать веб-службу WCF, но тот же синтаксис не работает , поскольку возвращаемый массив помещается в контейнерный объект 'd' :

{"d":
    [ 
    { "id": "Passer domesticus", "label": "House Sparrow", "value": "House Sparrow" },
    ...
    ]
}

Конечно, я могу обойти это, написав код для просмотра контейнера "d", что-то вроде следующего (непроверенного - может иметь опечатки):

$( "#birds" ).autocomplete({
minLength: 2
     source: function (request, response) {
            $.getJSON("search.svc/GetBirds", request, function (data, status, xhr) {
                if (status == "success") response(data.d);
                }
            }
});

Это лучшее, что я могу сделать, или есть более краткий синтаксис?

В идеале я хотел бы иметь возможность указать «источник» в качестве URL-адреса и заставить его работать с ответами, которые возвращаются с контейнером «d» или без него.

1 Ответ

1 голос
/ 24 января 2012

На мой взгляд, у вас есть два варианта.

Первое - создать вспомогательную функцию, которая будет отображать результаты для вас. Это, вероятно, лучшее / простое решение. Простой код:

$( "#birds" ).autocomplete({
minLength: 2
     source: function (request, response) {
            $.getJSON("search.svc/GetBirds", request, function (data, status, xhr) {
                if (status == "success") 
                   handleResponse(data); //you write this function
                }
            }
});

Второй параметр позволяет «monkeypatch» плагин AutoComplete функционировать для переопределения поведения по умолчанию.

Итак, в вашем случае вы хотите переопределить функцию $.ui.autocomplete.prototype._initSource. Честное предупреждение, что вы в основном переопределяете основную функцию в библиотеке пользовательского интерфейса, и если эта библиотека когда-либо обновляется, ваша функция всегда будет переопределять ее.

// Create a closure so that we can define intermediary
// method pointers that don't collide with other items
// in the global name space. 

function monkeyPatchAutocomplete() {

    // don't really need this, but in case I did, I could store it and chain 
    var oldFn = $.ui.autocomplete.prototype._renderItem;
    var requestIndex = 0;
    $.ui.autocomplete.prototype._initSource = function() {
        // whatever
        console.log("Override method");
        var self = this,
            array, url;
        if ($.isArray(this.options.source)) {
            array = this.options.source;
            this.source = function(request, response) {
                response($.ui.autocomplete.filter(array, request.term));
            };
        } else if (typeof this.options.source === "string") {
            url = this.options.source;
            this.source = function(request, response) {
                if (self.xhr) {
                    self.xhr.abort();
                }
                self.xhr = $.ajax({
                    url: url,
                    data: request,
                    dataType: "json",
                    autocompleteRequest: ++requestIndex,
                    success: function(data, status) {
                        console.log("Override success function, handling request");
                        if (this.autocompleteRequest === requestIndex) {
                            response(data); //you handle both types of data here
                        }
                    },
                    error: function() {
                        console.log("Override error function, handling request");
                        if (this.autocompleteRequest === requestIndex) {
                            response([]);
                        }
                    }
                });
            };
        } else {
            this.source = this.options.source;
        }
    };
}


// When DOM is ready, initialize.
$(document).ready(function() {
    monkeyPatchAutocomplete();

    $("#birds").autocomplete({
        source: "http://jqueryui.com/demos/autocomplete/search.php",
        minLength: 2
    });

});

Тогда вашему коду не нужно выполнять что-то другое, он просто обрабатывает различия и передает его в метод успеха.

Вот для этого jsFiddle: http://jsfiddle.net/lemkepf/DAQ6s/5/ Примечание: фактическое автозаполнение не будет работать, так как междоменная безопасность установлена. Вы можете открыть firebug и увидеть строчку console.debug, когда начнете вводить текст в поле.

...