我希望有一种方法可以让视图以通用的方式从控制器中关注特定的模型属性。
到目前为止我所拥有的是:
控制器:
// To become an extension/base class method
private void FocusOnField<TModel, TProperty>(Expression<Func<TModel, TProperty>> fieldExpression)
{
ViewData["FieldToFocus"] = fieldExpression;
}
...
FocusOnField((ConcreteModelClass m) => m.MyProperty);
看法
public static class ViewPageExtensions
{
public static MvcHtmlString FocusScript<TModel>(this ViewPage<TModel> viewPage)
{
if (viewPage.ViewData["FieldToFocus"] != null)
{
return MvcHtmlString.Create(
@"<script type=""text/javascript"" language=""javascript"">
$(document).ready(function() {
setTimeout(function() {
$('#" + viewPage.Html.IdFor((System.Linq.Expressions.Expression<Func<TModel, object>>)viewPage.ViewData["FieldToFocus"]) + @"').focus();
}, 500);
});
</script>");
}
else
{
return MvcHtmlString.Empty;
}
}
}
我现在面临的问题是,在视图的FocusScript
方法中,我不知道要关注的属性的返回类型,并且(System.Linq.Expressions.Expression<Func<TModel, object>>)
对于任何不返回对象的属性,转换为失败。
我不能只为属性添加第二个通用参数,因为我不知道控制器希望我关注的属性的返回类型是什么。
如何以通用方式编写我的视图扩展方法FocusScript
,以便它可以与不同返回类型的属性一起使用?
为什么会出现问题?
我知道我可以在控制器中传递我想要关注的控件的 ID,并让 javascript 读取该 ID,找到控件并关注它。但是,我不喜欢在控制器中硬编码属于视图(控件的 ID)的东西。我想告诉方法我想要什么属性,它应该知道要使用的 Id,就像视图通常获取/创建控件的 Id 一样。
假设我有一个模型:
class MyModel
{
public int IntProperty { get; set; }
public string StringProperty { get; set; }
}
在控制器的不同位置,我想关注一个不同的领域:
FocusOnField((MyModel m) => m.IntProperty);
...
FocusOnField((MyModel m) => m.StringProperty);
现在,在第一种情况下,表达式是一个返回整数的函数,在第二种情况下,它返回一个字符串。结果,我不知道将我的 ViewData["FieldToFocus"] 转换为(将其传递给IdFor<>()
)什么,因为它根据属性而有所不同..