2013-03-23 13 views
5

Pomyślałem, że bardzo użyteczne byłoby posiadanie rozszerzonej wersji programu pomocniczego EditorFor HTML, który automatycznie zapisuje wiązania danych wartości dla Knockout JS.EditorFor HTML Helper z nokautem

Dotyczy to sytuacji, w której model widoku po stronie klienta i model widoku po stronie serwera są takie same - już wygenerowałem automatycznie model widoku po stronie klienta za pomocą mapowania ko i uzyskując model view za pośrednictwem AJAX.

Czy ktoś próbował coś takiego, czy są jakieś projekty, które zawierają coś podobnego do tego, co tu myślę?

Zaletą tego jest to, że podczas refaktoryzacji nie byłoby niebezpieczeństwa utraty wartości związanych z danymi.

+1

Czy wiesz o http://knockoutmvc.com/? Chociaż słyszałem złe rzeczy na ten temat http://stackoverflow.com/questions/11618042/is-there-a-reason-i-would-use-knockout-mvc-instead-of-knockout-js. Możesz jednak ukraść kilka rozszerzeń :) –

+0

Spójrz na to dzięki –

+0

Rozpocząłem podobny projekt dla tego z powrotem w MVC3, ale kiedy usłyszeliśmy o szablonie aplikacji Single Page z integracją Knockout w MVC4, przestałem nad tym pracować. Niestety to się nie spełniło i nigdy nie wróciliśmy do projektu. Teraz wierzę, że funkcja ta powraca (lub powróciła) w dodatku SP2. –

Odpowiedz

3

Zrobiliśmy coś podobnego, co jest dalekie od doskonałości, i mamy znacznie więcej w naszych niestandardowych rozszerzeniach, ale wydobyłem esencję.

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

ten może być następnie wykorzystane jak:

@Html.TextBoxForViewModel(m => m.Name) 
1

chcielibyście dodać przeciążenie htmlAttributes do odpowiedzi Czadu powyżej dla każdego, kto chce go upuszczać i nie działać. Wszystkich innych pomocników można łatwo zbudować na podstawie tych przykładów. (Dzięki Chad, twoje rozszerzenie pomogło mi w przejściu do nokautu!)

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; 
     } 
    } 
} 
Powiązane problemy