【发布时间】:2012-07-12 03:22:35
【问题描述】:
我希望有一种方法可以让视图以通用方式从控制器中关注特定模型属性。
我目前拥有的是:
控制器:
// 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<>()),因为它因属性而异..
【问题讨论】:
-
在视图模型中完成所有管道并将视图键入到该视图模型中是否可行?那么您就可以访问属性而不必担心返回类型。
-
您的意思是模型中有
FocusScript方法?我仍然不确定这将如何工作,因为控制器可能希望绑定到该模型上的许多不同属性(具有不同的返回类型)。如果您认为它会起作用,我会很感激一个代码示例,因为也许我没有正确遵循。 -
你能解释一下你所说的不同返回类型是什么意思吗?为什么你需要知道这一点?
-
我问是因为 javascript focus() 只需要知道要关注的元素而不是视图模型类的属性信息
-
你不能不显眼吗?例如,从您的角度来看,在您想要关注的元素上添加一个
data-focus属性,然后有一个通用脚本在加载时关注这个元素?如果您更愿意在模型和视图上执行此操作,您甚至可以使用自定义属性来执行此操作,尽管我认为这是视图问题,而不是模型或控制器问题。
标签: c# asp.net-mvc model-view-controller generics asp.net-mvc-2