2013-03-23 11 views
5

Ich dachte, es wäre sehr nützlich, eine erweiterte Version von der EditorFor HTML-Helfer, die automatisch Wert Datenbindungen für Knockout JS schreibt.EditorFor HTML-Helfer mit Knockout

Dies wäre für wo das Client-Seitenansicht-Modell und das Server-Seitenansicht-Modell identisch sind - Ich habe bereits das Client-Seitenansicht-Modell mithilfe von Ko-Mapping erstellt und das Ansichtsmodell über AJAX erhalten.

Hat jemand sonst etwas versucht, oder gibt es irgendwelche Projekte, die etwas enthalten, was ich hier denke?

Der Vorteil davon wäre, dass beim Refactoring keine Gefahr besteht, dass die Datenwerte verpasst werden.

+1

Wissen Sie über http://knockoutmvc.com/? Obwohl ich schlechte Dinge darüber gehört habe http://stackoverflow.com/questions/11618042/is-there-a-reason-i-wool-use-knockout-mvc-instead-of-knockout-js. Allerdings könntest du wahrscheinlich ein paar Erweiterungen davon stehlen :) –

+0

Ich werde mir das mal ansehen –

+0

Ich habe ein ähnliches Projekt für diese Seite in MVC3 gestartet, aber als wir von der Single Page App-Vorlage mit Knockout-Integration in MVC4 gehört haben habe aufgehört, daran zu arbeiten. Leider ist dies nicht eingetreten und wir sind nie wieder zum Projekt gekommen. Jetzt glaube ich, dass das Feature in SP2 zurückkehrt (oder zurückgegeben wurde). –

Antwort

3

Wir haben etwas in diese Richtung getan, es ist alles andere als perfekt, und wir haben viel mehr in unseren benutzerdefinierten Erweiterungen, aber ich extrahierte die Essenz. Diese

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

kann dann verwendet werden, wie:

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

Wollte das Htmlattributes Überlastung Tschads Antwort oben für jedermann hinzuzufügen suchen, um es fallen zu lassen in und haben es funktionieren. Alle anderen Helfer können aus diesen Beispielen ziemlich einfach gebaut werden. (Danke, Chad, Ihre Erweiterung hat mir geholfen, meinen Übergang zum Knockout zu erleichtern!)

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