2016-12-13 3 views
0

동적 HTML 클래스를 처리하기 위해 내 견해. 메서드 내에서 switch를 사용하여 가능한 vehicleStatus 상태를 반복하고 그에 따른 부트 스트랩 클래스를 할당합니다. I.E. vehicleStatus = 2 인 경우 패널 패널 성공 - vehicleStatus = 2 인 경우 패널 패널 위험 :우아한 방법은 내가 지금처럼, 사용자 정의 MVC HTML 도우미 메서드가 MVC

그러나 VehicleStatus의 특정 반환 상태를 기반으로 다시 특정 글리프콘을 할당 할 수 있습니다. 앞으로는 더 많은 클래스 유형이 추가 될 것입니다.

이 헬퍼 메서드를 호출 할 때 필자는 classType (예 : 패널 또는 글리프콘)을 전달하려고합니다. 그리고 도우미 메서드에서 각 가능한 클래스 유형에 대한 스위치 코드를 복제 할 필요없이 특정 클래스 유형을 렌더링하는 우아한 솔루션을 원합니다. 내보기이 적절하게 할당 된 클래스/클래스 유형을 사용하여 TagBuilder div를 요청하고 반환합니다. 같은 그 : 문제의 당신의 묘사는 기본 클래스 또는 인터페이스 설정 (기본 클래스의 동작을 재정 의하여 미래에 추가 클래스 유형을 추가 할 수있는 가능성 중 하나의 완벽한 예처럼 소리

@Html.Div(vehicleStatus, "panel") 
// Would resolve and return, if vehicleStatus was 1: 
<div class="panel panel-success"> </div> 

// Calling the same method, vehicleStatus = 1 but expecting a respective 
// glyphicon: 
@Html.Div(vehicleStatus, "glyphicon") 
<div class="glyphicon glyphicon-remove-circle"> </div> 

답변

0

음 및/또는 인터페이스를 다르게 구현하는 것).

이것은 귀하가 찾고있는 것과 다를 수도 있습니다. 나는 전형적으로 도메인에서 비슷한 패턴을 사용했지만 때로는 면도기의 목적을 위해 사용했습니다. 이 경우 기본 클래스를 사용할 수 있습니다. 마무리 작업을 마치고이 예제를 약간 수정했다. 당신이 원하는 수준에 도달 할 때까지 아마 2 단계로 쉽게 벗어날 수 있습니다.

public abstract class HtmlTag 
{ 
    private readonly String _tag; 

    //allow different type of tags to be rendered 
    protected HtmlTag(String tag) 
    { 
     if (String.IsNullOrWhiteSpace(tag)) 
      throw new ArgumentException("Value cannot be null or whitespace.", "tag"); 
     _tag = tag; 
    } 
    //require a VehicleStatus for rendering to an HtmlString 
    public String ToHtmlString(VehicleStatus vehicleStatus) 
    { 
     var tag = new TagBuilder(_tag); 
     this.CreateTag(tag, vehicleStatus); 
     return tag.ToString(); 
    } 
    //require subclasses to implement the CreateTag method 
    //this method will allow subclasses to modify the tag builder as needed 
    //depending on the vehicle status 
    protected abstract void CreateTag(TagBuilder tagBuilder, VehicleStatus vehicleStatus); 
} 

, 당신은 구체적으로 예를 들어 div 또는 span, 원 다음 경우 :

public abstract class Div : HtmlTag 
{ 
    protected Div() 
     : base("div") 
    { 
    } 
} 
public abstract class Span : HtmlTag 
{ 
    protected Span() 
     : base("span") 
    { 
    } 
} 

그리고 마지막으로, 당신이 할 필요가 CreateTag 방법 implment 클래스를 만드는 것입니다 :

public class PanelDiv : Div 
{ 
    protected override void CreateTag(TagBuilder tagBuilder, VehicleStatus vehicleStatus) 
    { 
     tagBuilder.AddCssClass("panel"); 
     tagBuilder.AddCssClass(vehicleStatus == VehicleStatus.Success 
      ? "panel-success" 
      : "panel-danger"); 
    } 
} 
public class GlyphiconDiv : Div 
{ 
    protected override void CreateTag(TagBuilder tagBuilder, VehicleStatus vehicleStatus) 
    { 
     tagBuilder.AddCssClass("glyphicon"); 
     tagBuilder.AddCssClass(vehicleStatus == VehicleStatus.Success 
      ? "glyphicon-remove-circle" 
      : "glyphicon-add-circle"); 
    } 
} 

다른 유형을 추가하려면 다음을 수행해야합니다.

public class MyOtherDiv : Div 
{ 
    protected override void CreateTag(TagBuilder tagBuilder, VehicleStatus vehicleStatus) 
    { 
     //adjust the tag here based on vehicle status 
    } 
} 

그리고 마지막으로, 당신의 Html 헬퍼 :

public abstract class Div : HtmlTag 
{ 
    private readonly String _className; 
    private readonly String _trueCssClass; 
    private readonly String _falseCssClass; 

    protected Div(String className, String trueCssClass, String falseCssClass) 
     : base("div") 
    { 
     _className = className; 
     _trueCssClass = trueCssClass; 
     _falseCssClass = falseCssClass; 
    } 
    //the div will use the constructing parameters to populate the classes instead 
    protected override void CreateTag(TagBuilder tagBuilder, VehicleStatus vehicleStatus) 
    { 
     tagBuilder.AddCssClass(_className); 
     tagBuilder.AddCssClass(vehicleStatus == VehicleStatus.Success 
      ? _trueCssClass 
      : _falseCssClass); 
    } 
} 
//and your subclass: 
public class PanelDiv : Div 
{ 
    public PanelDiv() 
     : base("panel", "panel-success", "panel-danger") 
    { 
    } 
} 
: 당신이 또 다시 같은 조건을하는 자신을 발견 할 경우

public static class DivHtmlHelperExtensions 
{ 
    public static IHtmlString Div(this HtmlHelper htmlHelper, VehicleStatus vehicleStatus, HtmlTag htmlTag) 
    { 
     //simply return the HtmlString representation of your HtmlTag you passed in 
     return new HtmlString(htmlTag.ToHtmlString(vehicleStatus)); 
    } 
    //call this method likeso (from a view): 
    //@Html.Div(vehicleStatus, new PanelDiv()); 
    //@Html.Div(vehicleStatus, new GlyphiconDiv()); 
} 

, 당신은 약간의 책임을 더 처리 할 수있는 부모 클래스를 리팩토링 수

이것이 원하는 것이 아니라면 알려주십시오.

+0

제임스에게 매우 철저한 답변을 해주셔서 감사합니다! 내일 제공된 솔루션을 더 자세히 다룰 것입니다. 또한 TagBuilder를 사용하는 것이 일반적으로 중첩되어 div에 가장 적합하지 않을 수 있으며 TagRenderMode.StartTag를 사용할 수는 있지만 수동으로 추가 한 div 태그 만 볼 수 있기 때문에 컴파일 타임에 제대로 해결할 수 없다는 것을 알았습니다. 이것에 대한 더 이상의 제안? 그렇지 않으면 내일 StringBuilder를 사용하여 제안을 시도 할 것입니다. 다시 한 번 감사드립니다! –

+0

저는 지난 1 년 동안 만든 맞춤 HtmlTagBuilder를 사용합니다.필자는 저장소에 공개적으로 게시하는 일을 결코 해 보지 못했지만 그 이유는 알지 못했습니다. 이것은 내가 사용하는 것입니다 (시간이 지남에 따라 천천히 업데이트됩니다) : https://bitbucket.org/ThunderSizzle/thunder.helpers/src/31f1ed8ec99312df208ec1af696207c7258e2e04/Helpers.Html/HtmlTagBuilder.cs?at=default&fileviewer=file-view-default. 수행 할 수있는 성능 최적화가 있지만 현재 코드의 주요 최적화를 아직 요구하지 않은 것은 없습니다. 나는 지금 어떤 문서도 가지고 있지 않다. 그래서 미안하다. –

+0

좋아, 웬일인지, 나는 HtmlTagBuilder를 사용하는 예를 시험해보기로했다. (테스트되지 않은 기능을 추가하는 것과 함께 철저한 테스트 등을 통해 분명히 사용한다.) Html.BeginForm()과 같이 면도기 뷰에서 html을 추가 할 수있는 버전을 볼 수 있습니다. 나는 개인적으로 그 기능을 잠시 동안 원했고, 결코 그 기능을 사용하지 못했습니다. 여기에서 볼 수 있습니다 : https://bitbucket.org/ThunderSizzle/thunder.helpers/src/9a65c64cf78a34077f0807856c4bde92eafb480d/Thunder.Helpers.Examples/VehicleStatusExample/VehicleStatusModels.cs?at=default&fileviewer=file-view-default –

관련 문제