主要的CSS文件和核心的JQuery文件被留下来了,因为css在每个也都需要,并且绝大多数网页也需要JQuery。然而新的JQuery文件和不唐突的AJAX不是每个页面都需要的。
现在,有两种方式使用Autocomplete插件:
1.在javascript中设置要搜索的数据。
2.当用户输入时通过ajax检索。
在我使用这个插件的经验看来,我发现使用解决方案1时自动完成更快。因为它并不需要每次从数据库中请求数据。然而,使用这种解决方案的限制:只有这么多字符,可传递到function中,大量的JavaScript可能会导致用户的计算机上页面加载缓慢。经过一些试验和错误,我已经确定神奇的数字是大约40,000个结果。如果结果数量超过此,最好使用选项2;否则,始终坚持,因为搜索选项1是瞬时,而不是有轻微的延迟。
在这个例子中,将搜索书籍,我们没有超过40000,所以将使用选项1。BooksController现在必须更新,以设置ViewBag为booktitle。自动完成功能需要支持一个JavaScript数组的支持,所以书将管道(|)分开。然后在view中,书将被转换到一个数组,使用JavaScript的split()函数。当用户完成键入他们的结果,他们应该有选择完全匹配标题,因此这个函数将被更新。如果只有1本书返回并且用户执行了搜索,它会自动重定向到本书详细介绍页面。
我们要在bookcontroller中更新IndexAction并添加一个私有方法名为:FormatBooksForAutocomplete。
代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Data;
usingSystem.Data.Entity;
usingSystem.Linq;
usingSystem.Linq.Dynamic;
usingSystem.Web;
usingSystem.Web.Mvc;
usingMvcApplication.Models;
usingMvcApplication.Utils;
usingPagedList;
namespaceMvcApplication.Controllers
{
publicclassBooksController:Controller
{
privateBookDBContextdb=newBookDBContext();
//
//GET:/Books/
[OutputCache(Duration=Int32.MaxValue,SqlDependency="MvcApplication.Models.BookDBContext:books",VaryByParam="sortOrder;filter;page")]
publicActionResultIndex(stringsortOrder,stringfilter,stringKeyword,intpage=1)
{
#regionViewBagResources
ViewBag.Title=Resources.Resource1.BookIndexTitle;
ViewBag.CreateLink=Resources.Resource1.CreateLink;
ViewBag.TitleDisplay=Resources.Resource1.TitleDisplay;
ViewBag.IsbnDisplay=Resources.Resource1.IsbnDisplay;
ViewBag.SummaryDisplay=Resources.Resource1.SummaryDisplay;
ViewBag.AuthorDisplay=Resources.Resource1.AuthorDisplay;
ViewBag.ThumbnailDisplay=Resources.Resource1.ThumbnailDisplay;
ViewBag.PriceDisplay=Resources.Resource1.PriceDisplay;
ViewBag.PublishedDisplay=Resources.Resource1.PublishedDisplay;
ViewBag.EditLink=Resources.Resource1.EditLink;
ViewBag.DetailsLink=Resources.Resource1.DetailsLink;
ViewBag.DeleteLink=Resources.Resource1.DeleteLink;
#endregion
#regionViewBagSortParams
ViewBag.TitleSortParam=(sortOrder=="Title")?"Titledesc":"Title";
ViewBag.IsbnSortParam=(sortOrder=="Isbn")?"Isbndesc":"Isbn";
ViewBag.AuthorSortParam=(sortOrder=="Author")?"Authordesc":"Author";
ViewBag.PriceSortParam=(sortOrder=="Price")?"Pricedesc":"Price";
ViewBag.PublishedSortParam=(String.IsNullOrEmpty(sortOrder))?"Publisheddesc":"";
//Defaultthesortorder
if(String.IsNullOrEmpty(sortOrder))
{
sortOrder="Publisheddesc";
}
ViewBag.CurrentSortOrder=sortOrder;
#endregion
varbooks=frombindb.Booksselectb;
#regionKeywordSearch
if(!String.IsNullOrEmpty(Keyword))
{
books=books.Where(b=>b.Title.ToUpper().Contains(Keyword.ToUpper())||b.Author.ToUpper().Contains(Keyword.ToUpper()));
//Shouldweredirectbecauseofonlyoneresult?
if(books.Count()==1)
{
Bookbook=books.First();
returnRedirectToAction("Details",new{id=book.ID});
}
}
ViewBag.CurrentKeyword=String.IsNullOrEmpty(Keyword)?"":Keyword;
#endregion
#regionFilterswitch
switch(filter)
{
case"NewReleases":
varstartDate=DateTime.Today.AddDays(-14);
books=books.Where(b=>b.Published<=DateTime.Today.Date
&&b.Published>=startDate
);
break;
case"ComingSoon":
books=books.Where(b=>b.Published>DateTime.Today.Date);
break;
default:
//Nofilterneeded
break;
}
ViewBag.CurrentFilter=String.IsNullOrEmpty(filter)?"":filter;
#endregion
books=books.OrderBy(sortOrder);
intmaxRecords=1;
intcurrentPage=page-1;
//Getallbooktitles
ViewBag.BookTitles=FormatBooksForAutocomplete();
returnView(books.ToPagedList(currentPage,maxRecords));
}
privatestringFormatBooksForAutocomplete()
{
stringbookTitles=String.Empty;
varbooks=frombindb.Booksselectb;
foreach(Bookbookinbooks)
{
if(bookTitles.Length>0)
{
bookTitles+="|";
}
bookTitles+=book.Title;
}
returnbookTitles;
}
//
//GET:/Books/Details/5
publicActionResultDetails(intid=0,stringbookTitle="")
{
Bookbook=db.Books.Find(id);
returnView(book);
}
//
//GET:/Books/Create
publicActionResultCreate()
{
returnView();
}
//
//POST:/Books/Create
[HttpPost]
publicActionResultCreate(Bookbook,HttpPostedFileBasefile)
{
if(ModelState.IsValid)
{
//Uploadourfile
book.Thumbnail=FileUpload.UploadFile(file);
db.Books.Add(book);
db.SaveChanges();
returnRedirectToAction("Index");
}
returnView(book);
}
//
//GET:/Books/Edit/5
publicActionResultEdit(intid)
{
Bookbook=db.Books.Find(id);
returnView(book);
}
//
//POST:/Books/Edit/5
[HttpPost]
publicActionResultEdit(Bookbook,HttpPostedFileBasefile)
{
if(ModelState.IsValid)
{
//Deleteoldfile
FileUpload.DeleteFile(book.Thumbnail);
//Uploadourfile
book.Thumbnail=FileUpload.UploadFile(file);
db.Entry(book).State=EntityState.Modified;
db.SaveChanges();
returnRedirectToAction("Index");
}
returnView(book);
}
//
//GET:/Books/Delete/5
publicActionResultDelete(intid)
{
Bookbook=db.Books.Find(id);
returnView(book);
}
//
//POST:/Books/Delete/5
[HttpPost,ActionName("Delete")]
publicActionResultDeleteConfirmed(intid)
{
Bookbook=db.Books.Find(id);
//Deleteoldfile
FileUpload.DeleteFile(book.Thumbnail);
db.Books.Remove(book);
db.SaveChanges();
returnRedirectToAction("Index");
}
protectedoverridevoidDispose(booldisposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
最后book/indexview需要更新去初始化jQuery的自动完成。要做的第一件事是使用@节标记,包括必要的JavaScript和CSS文件。接下来,以前创建的搜索文本框更新设置一个键的IDwordSearch。
最后,JavaScript代码添加在视图的底部去在搜索文本框上建立自动完成功能。此JavaScript是有意添加在view的底部,以确保完全呈现给用户,因为在用户的电脑上建立数据是一项工作,Javascript处理可能会“堵塞”页面加载。
(译者:先呈现数据再执行javascript,js不是像传统那样放在head标签里)
这取决于结果的数量。代码如下:
@modelPagedList.IPagedList
@if(IsAjax)
{
Layout=null;
}
@sectionJavascriptAndCSS{
}
@MvcApplication4.Resources.Resource1.BookIndexTitle
@Html.ActionLink("CreateNew","Create")
Show:
@if(ViewBag.CurrentFilter!="")
{
@Ajax.ActionLink("All","Index",new{sortOrder=ViewBag.CurrentSortOrder,Keyword=ViewBag.CurrentKeyword},newAjaxOptions{UpdateTargetId="main"})
}
else
{
@:All
}
|
@if(ViewBag.CurrentFilter!="NewReleases")
{
@Ajax.ActionLink("NewReleases","Index",new{filter="NewReleases",sortOrder=ViewBag.CurrentSortOrder,Keyword=ViewBag.CurrentKeyword},newAjaxOptions{UpdateTargetId="main"})
}
else
{
@:NewReleases
}
|
@if(ViewBag.CurrentFilter!="ComingSoon")
{
@Ajax.ActionLink("ComingSoon","Index",new{filter="ComingSoon",sortOrder=ViewBag.CurrentSortOrder,Keyword=ViewBag.CurrentKeyword},newAjaxOptions{UpdateTargetId="main"})
}
else
{
@:ComingSoon
}
@using(Html.BeginForm())
{
@:Search:@Html.TextBox("Keyword",(string)ViewBag.CurrentKeyword,new{id="KeywordSearch"})
}
@Html.Partial("_Paging")
@Ajax.ActionLink("Title","Index",new{sortOrder=ViewBag.TitleSortParam,filter=ViewBag.CurrentFilter,Keyword=ViewBag.CurrentKeyword},newAjaxOptions{UpdateTargetId="main"})
|
@Ajax.ActionLink("Isbn","Index",new{sortOrder=ViewBag.IsbnSortParam,filter=ViewBag.CurrentFilter,Keyword=ViewBag.CurrentKeyword},newAjaxOptions{UpdateTargetId="main"})
|
Summary
|
@Ajax.ActionLink("Author","Index",new{sortOrder=ViewBag.AuthorSortParam,filter=ViewBag.CurrentFilter,Keyword=ViewBag.CurrentKeyword},newAjaxOptions{UpdateTargetId="main"})
|
Thumbnail
|
@Ajax.ActionLink("Price","Index",new{sortOrder=ViewBag.PriceSortParam,filter=ViewBag.CurrentFilter,Keyword=ViewBag.CurrentKeyword},newAjaxOptions{UpdateTargetId="main"})
|
@Ajax.ActionLink("Published","Index",new{sortOrder=ViewBag.PublishedSortParam,filter=ViewBag.CurrentFilter,Keyword=ViewBag.CurrentKeyword},newAjaxOptions{UpdateTargetId="main"})
|
|
@foreach(variteminModel)
{
@Html.DisplayFor(modelItem=>item.Title)
|
@Html.DisplayFor(modelItem=>item.Isbn)
|
@Html.DisplayFor(modelItem=>item.Summary)
|
@Html.DisplayFor(modelItem=>item.Author)
|
@Html.DisplayFor(modelItem=>item.Thumbnail)
|
@Html.DisplayFor(modelItem=>item.Price)
|
@Html.DisplayFor(modelItem=>item.Published)
|
@Html.ActionLink("Edit","Edit",new{id=item.ID})|
@Html.ActionLink("Details","Details",new{id=item.ID})|
@Html.ActionLink("Delete","Delete",new{id=item.ID})
|
}
@Html.Partial("_Paging")
$(document).ready(function(){
vardata="@ViewBag.BookTitles".split("|");
$("#KeywordSearch").autocomplete(data);
});
为了实施选项2,一个Ajax搜索,而不是传递数据数组到自动完成函数,您可以传递一个URL。URL将需要接受查询字符串变量:q。这包含用户输入的搜索值。这将用于执行书本上包含部分匹配的搜索,并返回以分隔符分隔的字符串。JQuery文档中含有较多的这样的成品例子,也有其他的例子,去更新的输出结果(可能包括书的封面的缩略图)。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。