在ASP.NET中使用JQuery UI自动完成的有效方法

Efficient way of using JQuery UI Autocomplete with ASP.NET

本文关键字:方法 有效 UI NET ASP JQuery      更新时间:2023-10-18

我的ASP.NET-C#网站正在使用JQuery UI Autocomplete。

JavaScript:

$(function () {
        var availableTags = [
            <%=GetAvaliableTags() %>
        ];
        $("input.tag_list").autocomplete({
            source: availableTags
        });
    });

C#代码背后的功能:

public string GetAvaliableTags()
{
    var tags = new[] { "ActionScript", "Scheme" };
    return String.Join(",", tags.Select(x => String.Format("'"{0}'"", x)));
}

这很好用。但我有一个疑问,如果我从数据库中获取大量的标签,它会在页面加载时同时加载所有这些标签,使其速度变慢。我想到的最有效的方法是使用Ajax。但我不是Ajax程序员,对它知之甚少。有人能告诉我如何有效地使用Ajax吗?如何按需呼叫GetAvailableTags

更新

我试过这样:

 $(function () {
                var availableTags = [function () {
                    $.ajax({
                        type: "POST",
                        contentType: "application/json; charset=utf-8",
                        url: "CreateTopic.aspx/GetAvaliableTags",
                        data: "{ 'key' : '" + $("input.tag_list").val() + "'}",
                        dataType: "json",
                        async: true,
                        dataFilter: function (data) { return data; },
                        success: function (data) {if (result.hasOwnProperty("d")) {
                          $("input.tag_list").autocomplete({
                              source: result.d
                          });
                      }
                      else {
                          // No .d; so just use result
                          $("input.tag_list").autocomplete({
                              source: result
                          });
                    });
                }];
                $("input.tag_list").autocomplete({
                    source: availableTags
                });
            });

等价于GetAvailableTags() 的Web方法

[System.Web.Services.WebMethod]
public static string GetAvaliableTags(string key)
{
    var tags = new[] { "ActionScript", "Scheme" };
    return String.Join(",", tags.Select(x => String.Format("'"{0}'"", x)));
}

但是Ajax调用并没有被触发。原因是什么?

我建议在服务器端使用ASP.NET AJAX页面方法,并让jQuery .ajax()函数调用它来检索数据,如下所示:

代码背后:

[WebMethod]
public static string GetAvailableTags()
{
    // Put logic here to return list of tags (i.e. load from database)
    var tags = new[] { "ActionScript", "Scheme" };
    return String.Join(",", tags.Select(x => String.Format("'"{0}'"", x)));
}

标记:

$(document).ready(function() {
    $.ajax({
        type: "POST",
        url: "PageName.aspx/GetAvailableTags",
        data: "{}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(result) {
            if (result.hasOwnProperty("d")) {
                // The .d is part of the result so reference it
                //  to get to the actual JSON data of interest
                $("input.tag_list").autocomplete({
                    source: result.d
                });
            }
            else {
                // No .d; so just use result
                $("input.tag_list").autocomplete({
                    source: result
                });
            }
        }
    });
});

注意:您需要将PageName.aspx的名称更改为.aspx页面的名称。此外,.d语法是微软在ASP.NET AJAX的ASP.NET 3.5版本中引入的反XSS保护;因此检查CCD_ 6属性是否存在。

我在intranet应用程序中实现了一个很好的解决方案;它使用带有HttpHandler的jQueryUIAutocomplete函数,并且只搜索以输入中的内容开头的客户;它也只有在键入了3个或更多字符时才会触发。这意味着您永远不会检索整个表,只检索其中的一个子集

首先是HttpHandler。我不会详细介绍数据检索的细节,因为你可能自己就能弄清楚这一部分。SUffice说,它调用一个存储过程来返回名称以开头的客户(无论发送给处理程序的是什么),并向自动完成处理程序返回一个JSON序列化的匹配数组。

using Newtonsoft.Json;
namespace Invoicing.HttpHandlers
{
    [WebService(Namespace = "yournamespace/http-handlers/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class CustomerHandler : IHttpHandler
    {
        #region IHttpHandler Members
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
        public void ProcessRequest(HttpContext context)
        {
          // your data-retrieval logic here
          // write json to context.Response
        }
    }

如果您不习惯这种方法,我将快速描述JSON部分。

基本上,我有一个名为"ResponseCustomer"的小型包装器类型对象,因为我只需要Autocomplete处理程序的Customer ID和Name,而不需要完整的Customer详细信息:-

[Serializable]
public class ResponseCustomer
{
    public int ID;
    public string CustomerName;
}

IHttpHandler.ProcessRequest调用我的存储过程,并将结果转换为IList-这意味着返回的JSON尽可能精简:-

    public void ProcessRequest(HttpContext context)
    {
        string json = string.Empty;
        // note the httpcontext.Request contains the search term
        if (!string.IsNullOrEmpty(context.Request["term"]))
        {
            string searchTerm = context.Request["term"];
            var customers = (data access component).CustomerSearch(searchTerm); // call Search stored proc
            if (customers.Count != 0)
            {
                var transformList = new List<ResponseCustomer>();
                for (int index = 0; index < customers.Count; index++)
                {
                    transformList.Add(new ResponseCustomer
                    {
                        ID = customers[index].ID,
                        CustomerName = customers[index].CustomerName
                    });
                }
                // call Newtonsoft.Json function to serialize list into JSON
                json = JsonConvert.SerializeObject(transformList);
            }
        }
        // write the JSON (or nothing) to the response
        context.Response.Write(json);
    }

到目前为止还不错吗?

请确保此HttpHandler已连接到web.config(注意,IIS6与IIS 7+的操作方式不同):-

      <system.web>
        <!-- Custom HTTP handlers (IIS 6.0) -->
        <httpHandlers>
          <add path="customerHandler.ashx" verb="*" type="(namespace).(handler name), (assembly name)" />
i.e.
      <add path="customerHandler.ashx" verb="*" type="MyProject.Handlers.CustomerHandler, MyProject" />
    and for IIS7: -

  <system.webServer>
    <handlers>
      <!-- Custom HTTP handlers (IIS7+) -->
      <add name="customerHandler" preCondition="integratedMode" verb="*" path="customerHandler.ashx" type="(namespace).(handler name), (assembly name)"" />

最后连接到客户端,正如您已经知道的:-

HTML:-

        <span>Customer</span>
        <span class="ui-widget" style="display:inline-block">
            <input id="txtCustomer" runat="server" clientidmode="Static" />
        </span>

JS:-

$(function ()
{
    $("#txtCustomer").autocomplete(
        {
            source: "customerHandler.ashx",
            // note minlength, triggers the Handler call only once 3 characters entered
            minLength: 3,
            select: function (event, ui)
            {
                if (ui.item)
                {
                    $("#txtCustomer").val(ui.item.CustomerName);
                    return false;
                }
            }
        })
        .data("autocomplete")._renderItem = function (ul, item)
        {
            // insert an item into the autocomplete dropdown (YMMV)
            return $("<li></li>")
                .data("item.autocomplete", item)
                .append("<a><table cellpadding='0' cellspacing='0' border='0' width='250px'><tr><td width='200' valign='top' align='left'>"
                + item.CustomerName + "</td><td width='50px' valign='top' align='left'>[ID "
                + item.ID + "]</td></tr></table></a>")
                .appendTo(ul);
        };
});

如果这有帮助,请告诉我,如果你愿意,我可以通过电子邮件向你发送相关的源文件。

如果您想要实时更新选项

    $(document).ready(function() {   
            $("textbox").autocomplete({
                source: function (request, response) {
                pageMethod.yourmethodname(request.term,onSuccess)
                function onSuccess(Responce){
                                  data = JSON.parse(Responce)
                                  response($.map(data.d, function (item) {
                                          return {
                                                 value: item
                                                  }
                                     }
    };