2013-02-22 1 views
3

내 목표는 MVC.Net보기에서 명령 체인을 허용하는 개체를 만드는 것입니다.HtmlHelper 객체를 반복적으로 전달하지 않고 MVC.Net에서 람다 식을 연결

<nav class="navigation"> 
    <%: Html 
     .menu() 
      .item("Introduction", "Introduction", "Home") 
      .item("About", "About", "Home") 
      .item("Systems", "Index", "Systems") 
      /*.item("Categories", "Categories", "Health")*/ 
      .item("Test Cases", "TestCases", "Testing") 
      .category("Logging") 
       .item("UniMon Events", "UniMonEvents", "Logging") 
      .end() 
     .end() %> 
</nav> 

는 여러 부분 사이의 상호 의존성이있는 다 계층 메뉴의 빠른 건설을 허용 당신이 볼 수 있듯이 : 여기

나는이 개념을 사용하여 만든 메뉴의보기에서 사용 예제입니다 .

람다 식을 사용하는 양식에 대해 이와 동일한 효과를 얻고 싶습니다.

이상적인 구문은 다음과 같습니다

<%: Html 
    .form() 
     .hidden(m=>m.property1) 
     .hidden(m=>m.property2) 
    .end() %> 

내가 곤경에 실행하고있는 숨겨진 방법이다. m 메서드에 전달하지 않고 컴파일러에서이 메서드를 전달할 방법이없는 것 같습니다.

나는이 구문 달성 할 수

:이 클래스 및 확장 메서드 (도시하지 않음)를 사용하여

<%: Html 
    .form() 
     .hidden(Html, m=>m.property1) 
     .hidden(Html, m=>m.property2) 
    .end() %> 

을 :

public class RouteForm 
{ 
    public HtmlHelper HtmlHelper { get; private set; } 
    public Dictionary<string, string> PostData { get; private set; } 

    public RouteForm(HtmlHelper htmlHelper) 
    { 
     HtmlHelper = htmlHelper; 
     PostData = new Dictionary<string, string>(); 
    } 

    public RouteForm hidden<TModel, TValue>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression) 
    { 
     string name = ExpressionHelper.GetExpressionText(expression); 
     string value = GetFieldValue(htmlHelper, expression); 
     PostData.Add(name, value); 
     return this; 
    } 
    private static string GetFieldValue<TModel, TValue>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression) 
    { 
     object oValue = expression.Compile()(htmlHelper.ViewData.Model); 
     string value = (oValue is Enum) ? ((int)oValue).ToString() : oValue.ToString(); 
     return value; ; 
    } 
    public MvcHtmlString end() 
    { 
     //TODO: render form with post data 
     return MvcHtmlString.Empty; 
    } 
} 

내가 아마 일반적인 유형의 클래스가 될 수 있다는 생각을 내가 찾고 있으므로이 시도 :

public class RouteForm<TModel> 
{ 
    public HtmlHelper<TModel> HtmlHelper { get; private set; } 
    public Dictionary<string, string> PostData { get; private set; } 

    public RouteForm(HtmlHelper<TModel> htmlHelper) 
    { 
     HtmlHelper = htmlHelper; 
     PostData = new Dictionary<string, string>(); 
    } 

    public RouteForm<TModel> hidden<TModel, TValue>(Expression<Func<TModel, TValue>> expression) 
    { 
     string name = ExpressionHelper.GetExpressionText(expression); 
     string value = GetFieldValue(expression); 
     PostData.Add(name, value); 
     return this;//ERRORS: TModel is TModel 
    } 
    private string GetFieldValue<TModel, TValue>(Expression<Func<TModel, TValue>> expression) 
    { 
     object oValue = expression.Compile()(
      (TModel)HtmlHelper.ViewData.Model //ERRORS: Cannot convert type TModel to TModel 
     ); 
     string value = (oValue is Enum) ? ((int)oValue).ToString() : oValue.ToString(); 
     return value; ; 
    } 
    public MvcHtmlString end() 
    { 
     //TODO: render form with post data 
     return MvcHtmlString.Empty; 
    } 
} 

위의 코드에서 주석을 사용하여 오류를 넣었습니다.

감사합니다.

답변

3

너무 많은 일반 매개 변수를 사용하고 있습니다.

GetFieldValue<TModel, ...>과 같은 메서드는 TModel 매개 변수를 만들어 첫 번째 매개 변수와 관련이 없습니다. 즉

, 그들은 당신이

new RouteForm<PersonModel>().GetFieldValue<TruckModel, ...>() 

작성 이것은 분명히 잘못된 것입니다 수 있습니다.

대신 각 메소드에서 해당 매개 변수를 제거하고 대신 클래스 'TModel 매개 변수를 사용하게하십시오.

+0

완료. 일단 당신이 그것을 지적하면 이것은 명백합니다. 다음과 같이 작성할 수 있습니다 : 새로운 mvc.RouteForm (Html) .hidden (m => m.Property); –

+0

명시 적으로 전달하는 대신 생성자에서 형식을 유추하도록 컴파일러를 가져 오는 방법이 있습니까? 새로운 mvc.RouteForm (Html) .hidden (m => m.Property); 주어진 생성자 : public RouteForm (HtmlHelper htmlHelper) –

+2

@Nathaniel : No; 타입 추론은 생성자에는 적용되지 않습니다. 대신 확장 메서드를 사용하십시오. – SLaks

1

"ERRORS : TModel is TModel"은 hidden()의 일반적인 선언에서 TModel을 두 번 선언하면 발생합니다.

은 내가이 컴파일하지 않은,하지만 난 이런 식으로 뭔가를 시도 할 것 :

public static class HtmlHelperExtensions 
{ 
    public static RouteForm<TModel> form(this HtmlHelper helper, TModel model) 
    { 
     return new RouteForm<TModel>(helper); 
    } 
} 

public class RouteForm<TModel> 
{ 
    public RouteForm<TModel> hidden(Expression<Func<TModel, TValue>> expression) 
    { 
    }   
    public MvcHtmlString end() 
    { 
    } 
} 
0

덕분에 내가 찾고 있던 구문을 달성하는 클래스를 생성 할 수 있었다 당신의 모두.

(클래스는 포스트에 대한 간략화) 분류 :

public class RouteForm<TModel> 
{ 
    public HtmlHelper<TModel> HtmlHelper { get; private set; } 

    public RouteForm(HtmlHelper<TModel> htmlHelper) 
    { 
     HtmlHelper = htmlHelper; 
    } 

    public RouteForm<TModel> hidden<TValue>(Expression<Func<TModel, TValue>> expression) 
    { 
     return this; 
    } 
    public MvcHtmlString end() 
    { 
     return MvcHtmlString.Empty; 
    } 
} 

확장 방법

public static RouteForm<TModel> form<TModel>(this HtmlHelper<TModel> helper) 
{ 
    return new RouteForm<TModel>(helper); 
} 

마크 업 구문 :

<%: Html 
    .form() 
     .hidden(m=>m.Property1) 
     .hidden(m=>m.Property2) 
    .end() 
%> 
관련 문제