EditorFor HTML助手与淘汰赛

问题描述:

我认为这将是非常有用的扩展版 EditorFor HTML助手,它会自动写出Knockout JS的值数据绑定。EditorFor HTML助手与淘汰赛

这将用于客户端视图模型和服务器端视图模型相同的地方 - 我已经通过使用ko映射并通过AJAX获取视图模型来自动生成客户端视图模型。

有没有其他人尝试过这样的事情,还是有任何项目包括类似于我在这里想的东西?

这样做的好处是,重构时不会有数据绑定值被遗漏的危险。

+1

你知道关于http://knockoutmvc.com/吗?虽然我听说过它的坏事http://*.com/questions/11618042/is-there-a-reason-i-would-use-knockout-mvc-instead-of-knockout-js。然而,你可能会从它偷一些扩展:) – 2013-03-23 23:14:19

+0

我会看看,谢谢 – 2013-03-23 23:32:33

+0

我在MVC3开始了一个类似的项目,但是当我们听说MVC4中带有Knockout集成的单页面应用程序模板时,我们停止对此工作。不幸的是,这并没有实现,我们从未回到项目。现在,我相信该功能正在返回(或已经返回)在SP2中。 – 2013-03-24 12:37:59

我们已经沿着这些方向做了一些事情,它远非完美,我们在自定义扩展中有更多的东西,但我提取了本质。

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) 

诚征全国htmlAttributes超载添加到乍得的回答上面的任何人都希望将它放在和它的工作。所有其他的助手都可以很容易地从这些例子中构建。 (谢谢乍得,你的扩展帮助我轻松过渡到使用淘汰赛!)

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; 
     } 
    } 
}