我认为拥有扩展版本非常有用 EditorFor HTML帮助程序,它自动为Knockout JS写出值数据绑定。
这适用于客户端视图模型和服务器端视图模型相同的地方 - 我已经通过使用ko映射并通过AJAX获取viewmodel来自动生成客户端视图模型。
有没有其他人尝试这样的事情,或者是否有任何项目包含类似于我在这里的想法?
这样做的好处是,在重构时,不会有错过数据绑定值的危险。
答案 0 :(得分:3)
我们已经沿着这些方向做了一些事情,它远非完美,我们在自定义扩展中有更多,但我提取了本质。
using System.Web.Mvc.Html;
namespace System.Web.Mvc
{
public static class EditorForExtensions
{
public static MvcHtmlString TextBoxForViewModel<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var htmlAttributes = HtmlAttributesForKnockout(metadata);
return htmlHelper.TextBoxFor(expression, htmlAttributes);
}
private static Dictionary<string, object> HtmlAttributesForKnockout(ModelMetadata metadata)
{
var htmlAttributes = new Dictionary<string, object>();
var knockoutParameter = String.Format("value: {0}", metadata.PropertyName);
htmlAttributes.Add("data-bind", knockoutParameter);
return htmlAttributes;
}
}
}
然后可以使用它:
@Html.TextBoxForViewModel(m => m.Name)
答案 1 :(得分:1)
希望将htmlAttributes重载添加到Chad上面的答案中,以便任何希望将其放入并使其工作的人。可以很容易地从这些示例构建所有其他帮助程序。 (感谢Chad,你的扩展帮助我轻松过渡到使用淘汰赛!)
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Web.Mvc.Html;
namespace System.Web.Mvc {
public static class KnockoutExtensions {
public static MvcHtmlString KnockoutTextBoxFor<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression ) {
var metadata = ModelMetadata.FromLambdaExpression( expression, htmlHelper.ViewData );
var htmlAttributes = HtmlAttributesForKnockout( metadata );
return htmlHelper.TextBoxFor( expression, htmlAttributes );
}
public static MvcHtmlString KnockoutTextBoxFor<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object attributes ) {
// convert passed anonymous object (attributes) into IDictionary<string,object> to pass into attribute parser
var attrs = HtmlHelper.AnonymousObjectToHtmlAttributes( attributes ) as IDictionary<string, object>;
var metadata = ModelMetadata.FromLambdaExpression( expression, htmlHelper.ViewData );
var htmlAttributes = HtmlAttributesForKnockout( metadata, attrs );
return htmlHelper.TextBoxFor( expression, htmlAttributes );
}
private static Dictionary<string, object> HtmlAttributesForKnockout( ModelMetadata metadata, IEnumerable<KeyValuePair<string, object>> attributes = null ) {
var htmlAttributes = new Dictionary<string, object>();
var knockoutParameter = String.Format( "value: {0}", metadata.PropertyName );
htmlAttributes.Add( "data-bind", knockoutParameter );
if ( attributes != null ) foreach ( var attr in attributes ) htmlAttributes.Add( attr.Key, attr.Value );
return htmlAttributes;
}
}
}