我正在使用timdwilson的预先package。不幸的是,当我将AutoCompleteFor
框放在for循环中时,我遇到了一个问题,因为lambda表达式与AutocompleteHelpers
类(特别是Expression
求值程序不匹配)。
基本上,我不是model => model.SelectedIngredeints[i]
而是model => model.SelectedIngredients.get_Item(value(ASP._Page_Views_Recipes_Create_cshtml+<>c__DisplayClass3_0).i)
无论如何,C#可以评估SelectedIngredients.get_Item(value(ASP._Page_Views_Recipes_Create_cshtml+<>c__DisplayClass3_0).i
只是SelectedIngredients[i]
吗?
如果我不清楚,这里有一些屏幕截图......
这里没有问题,因为model => model.testInt
已被(?)评估或引用。
但是,当我尝试使用我的迭代器时,会发生以下情况。
答案 0 :(得分:3)
我是timdwilson,我创建了你遇到麻烦的Twitter.Typeahead.MVC.Model NuGet包和typeahead-mvc-model GitHub存储库。在查看了您的问题之后,我发现确实,data-autocomplete-id-field
为输入元素的AutocompleteFor
属性生成的HTML应该是SelectedIngredients_0_
,而是SelectedIngredients.get_Item(value(ASP._Page_Views_Recipes_Create_cshtml+<>c__DisplayClass3_0).i)
}。
换句话说,你期待这个:
<input class="form-control typeahead" data-autocomplete-id-field="SelectedIngredients_12_" data-autocomplete-url="/Recipes/GetIngredients" id="SelectedIngredientsNames_12_" name="SelectedIngredientsNames[12]" type="text" value="" />
但是,相反,得到了这个:
<input class="form-control typeahead" data-autocomplete-id-field="SelectedIngredients.get_Item(value(ASP._Page_Views_Recipes_Create_cshtml+<>c__DisplayClass3_0).i)" data-autocomplete-url="/Recipes/GetIngredients" id="SelectedIngredientsNames_12_" name="SelectedIngredientsNames[12]" type="text" value="" />
由于data-autocomplete-id-field
用于在页面上查找此元素并设置其值,因此在选择预先输入值时,永远不会捕获所选的ID。
我通过正确生成HTML来修复此问题,与生成valueExpression
的方式相同。此修补程序将显示在Twitter.Typeahead.MVC.Model version 1.0.6 NuGet package中,并且已经签入typeahead-mvc-model GitHub repository。
要在本地副本中修复此问题,请使用以下代码替换Controllers \ HtmlHelpers文件夹中的AutocompleteHelpers类(或将其移动到的位置):
public static class HtmlHelpers {
/// <summary>
/// Extends MvcHtml to conditionaly display a value or empty string
/// </summary>
/// <param name="value">Value to be displayed if 'evaluation' is true</param>
/// <param name="evaluation"></param>
/// <returns></returns>
public static MvcHtmlString If(this MvcHtmlString value, bool evaluation) {
return evaluation ? value : MvcHtmlString.Empty;
}
/// <summary>
/// Extends MvcHtml to conditionaly display one of two possible values
/// </summary>
/// <param name="value">Value to be displayed if 'evaluation' is true</param>
/// <param name="evaluation"></param>
/// <param name="valueIfFalse">Value to be displayed if 'evaluation' is false</param>
/// <returns></returns>
public static MvcHtmlString If(this MvcHtmlString value, bool evaluation, MvcHtmlString valueIfFalse) {
return evaluation ? value : valueIfFalse;
}
}
public static class AutocompleteHelpers
{
public static MvcHtmlString AutocompleteFor<TModel, TProperty1, TProperty2>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty1>> valueExpression,
Expression<Func<TModel, TProperty2>> idExpression, string actionName, string controllerName, bool requestFocus)
{
return CreateTextBoxForFromAutocompleteFor<TModel, TProperty1, TProperty2>(html, valueExpression, actionName, controllerName, requestFocus,
idExpression.Body.ToString());
}
public static MvcHtmlString AutocompleteFor<TModel, TProperty1, TProperty2>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty1>> valueExpression,
Expression<Func<TModel, TProperty2>> idExpression, int index, string actionName, string controllerName, bool requestFocus)
{
// Get the fully qualified class name of the autocomplete id field
string idFieldString = idExpression.Body.ToString();
// handle if the id field is an array
int loc_get_Item = idFieldString.IndexOf(".get_Item(");
if (loc_get_Item > 0)
{
idFieldString = idFieldString.Substring(0, loc_get_Item);
idFieldString += string.Format("_{0}_", index);
}
var textBoxFor = CreateTextBoxForFromAutocompleteFor<TModel, TProperty1, TProperty2>(html, valueExpression, actionName, controllerName, requestFocus, idFieldString);
return textBoxFor;
}
private static MvcHtmlString CreateTextBoxForFromAutocompleteFor<TModel, TProperty1, TProperty2>(HtmlHelper<TModel> html,
Expression<Func<TModel, TProperty1>> valueExpression, string actionName, string controllerName, bool requestFocus, string idFieldString)
{
string autocompleteUrl = UrlHelper.GenerateUrl(null, actionName, controllerName,
null,
html.RouteCollection,
html.ViewContext.RequestContext,
includeImplicitMvcValues: true);
string @class = "form-control typeahead" + (requestFocus ? " focus" : string.Empty);
// We need to strip the 'model.' from the beginning
int loc = idFieldString.IndexOf('.');
// Also, replace the . with _ as this is done by MVC so the field name is js friendly
string autocompleteIdField = idFieldString.Substring(loc + 1, idFieldString.Length - loc - 1).Replace('.', '_');
var textBoxFor = html.TextBoxFor(valueExpression,
new {data_autocomplete_url = autocompleteUrl, @class, data_autocomplete_id_field = autocompleteIdField});
return textBoxFor;
}
}
如果此修复程序适合您,请接受此作为您问题的答案。如果您有任何其他问题或疑问,请告诉我。谢谢罗里!