好吧,经过大量的摆弄,我想出了以下实现:
下面的代码是一个HtmlHelper被调用的@Html.AutocompleteWithHiddenFor. HtmlHelper 将创建一个inputHTML 元素,该元素具有data-autocomplete-url基于controller和action传入的属性。
如果input元素需要 avalue那么您也可以将其传入。HiddenFor将为Model传入的属性创建A ,并且ValidationMessageFor还将为 the 创建Model。
现在我所要做的就是使用@Html.AutocompleteWithHiddenFor, 并通过控制器和操作(可能还有值)传递我需要的任何表达式,以获取自动完成功能并将 ID 传递给服务器而不是 text。
jQuery
$(function () {
function log(id, name) {
var hidden = $('#' + name);
hidden.attr("value", id);
}
$('*[data-autocomplete-url]')
.each(function () {
$(this).autocomplete({
source: $(this).data("autocomplete-url"),
minLength: 2,
select: function (event, ui) {
log(ui.item.id, ui.item.name);
},
change: function (event, ui) {
if (!ui.item) {
this.value = '';
} else {
log(ui.item.id, ui.item.name);
}
}
});
});
});
自动完成助手类
public static class AutocompleteHelper
{
/// <summary>
/// Given a Model's property, a controller, and a method that belongs to that controller,
/// this function will create an input html element with a data-autocomplete-url property
/// with the method the autocomplete will need to call the method. A HiddenFor will be
/// created for the Model's property passed in, so the HiddenFor will be validated
/// and the html input will not.
/// </summary>
/// <returns></returns>
public static MvcHtmlString AutocompleteWithHiddenFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, string controllerName, string actionName, object value = null)
{
// Create the URL of the Autocomplete function
string autocompleteUrl = UrlHelper.GenerateUrl(null, actionName,
controllerName,
null,
html.RouteCollection,
html.ViewContext.RequestContext,
includeImplicitMvcValues: true);
// Create the input[type='text'] html element, that does
// not need to be aware of the model
String textbox = "<input type='text' data-autocomplete-url='" + autocompleteUrl + "'";
// However, it might need to be have a value already populated
if (value != null)
{
textbox += "value='" + value.ToString() + "'";
}
// close out the tag
textbox += " />";
// A validation message that will fire depending on any
// attributes placed on the property
MvcHtmlString valid = html.ValidationMessageFor(expression);
// The HiddenFor that will bind to the ID needed rather than
// the text received from the Autocomplete
MvcHtmlString hidden = html.HiddenFor(expression);
string both = textbox + " " + hidden + " " + valid;
return MvcHtmlString.Create(both);
}
}
看法
@Html.LabelFor(model => model.RouteID, "Route")
@Html.AutocompleteWithHiddenFor(model => model.RouteID, "Route", "GetRoutesByUser")
或者如果它需要一个值
@Html.LabelFor(model => model.Route, "Route")
@Html.AutocompleteWithHiddenFor(model => model.RouteID, "Route", "GetRoutesByUser", @Model.RouteName)