2013-03-23 97 views
5

我認爲這將是非常有用的擴展版 EditorFor HTML助手,它會自動寫出Knockout JS的值數據綁定。EditorFor HTML助手與淘汰賽

這將用於客戶端視圖模型和服務器端視圖模型相同的地方 - 我已經通過使用ko映射並通過AJAX獲取視圖模型來自動生成客戶端視圖模型。

有沒有其他人嘗試過這樣的事情,還是有任何項目包括類似於我在這裏想的東西?

這樣做的好處是,重構時不會有數據綁定值被遺漏的危險。

+1

你知道關於http://knockoutmvc.com/嗎?雖然我聽說過它的壞事http://stackoverflow.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

回答

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

誠徵全國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; 
     } 
    } 
}