2013-02-12 2 views
2

속성 값에 따라 다른 이미지를 표시해야합니다.
이것은이 작업을 수행하는 나의 방법입니다. 나는 간단한 HTML을보기에서모델의 속성에 따라 다른 이미지 표시

private string GetImageFileNameForStatus(string status) 
{ 
    if (status == "payed" || status == "approved") 
     return "payed.png"; 

    if (status == "printed") 
     return "not-pay.png"; 

    if (status == "closed") 
     return "closed.png"; 

    if (status == "transfer") 
     return "transfer.png"; 

    return string.Empty; 
} 

:

public class DetailInfoViewModel 
{ 
    public string Status {get; set;} 
    public string StatusImageName {get; set;} 
    ... other fields 
} 

액션에서 :

var model = ...// create view model and fill properties  
model.StatusImageName = GetImageFileNameForStatus(model.Status.ToLower()); 

하고, 주요 방법

나는 모델이

<div class="pull-right"> 
    <img src="@Url.Content("~/Images/" + Model.StatusImageName)"/> 
</div> 

하지만이 방법은 추악합니다. 이미지의 이름을 바꾸거나 잘못 인쇄하면이 코드가 제대로 작동하지 않습니다.
더 좋은 방법이 있습니까? 내가

status | statusImage | 
---------------------- 
payed | payed.png | 
closed | closed.png | 
    ... |   ... | 

을 의미,

답변

1

은 덜 오류가 발생하기 쉬운 수 있도록 상태를 만드는 고려 열거

enum Status { Payed, Printed, Closed, Approved, Transfer} 

그리고 자원에 대한 강력한 링크를 생성하는 T4MVC를 사용 :

private string GetImageFileNameForStatus(Status status) 
{ 
    switch(status){ 
     case Payed: 
     case Approved: 
     // This is generated by T4MVC for you 
     return Links.Content.Images.payed_png; 
     case Printed: 
     return Links.Content.Images.not_pay_png;   
     // ... etc. 
     default: 
     return Links.Content.Images.default_png; 
    } 
} 

switch 문 대신 Dictionary<Status, string> 내부에 정보를 저장할 수 있지만 구현 세부 사항입니다.

그런 다음이 유사하게 사용할 수 있습니다

<img src="@Model.StatusImageName" alt="@Model.Status"/> 

NB가 : 알트 속성을 추가해야합니다!

이미지의 이름을 바꾸거나 이동하면 편집이 중단됩니다.

이 솔루션은 대부분의 소형 시스템에서 수용 가능해야합니다. 더 복잡한 "순수 OOP"솔루션 (유스 케이스에 따라 오버 엔지니어링으로 어려움을 겪을 수 있음)에 관심이 있다면 계속 읽어보십시오.

이 스위치는 순수 OOP 관점에서 보면 비교적 간단하지만 가장 아름다운 솔루션은 아닙니다. State Pattern (.NET implementation)을 고려해보세요.

interface IStatus{ 
    string InfoImage{get;} 
} 

class PayedStatus : IStatus {  
    public string InfoImage{get{return Links.Content.Images.payed_png;}} 
} 

class PrintedStatus : IStatus {  
    public string InfoImage{get{return Links.Content.Images.not_pay_png;}} 
} 

// etc. 

그리고 모델 :보기에

public class DetailInfoViewModel 
{ 
    ... 
    public IStatus Status{get;set;} 
} 

:

<img src="@Model.Status.InfoImage" alt="Status"/> 

이러한 접근 방식은 주어진 상태에 고유 한 일이있는 경우 더 나은입니다.각각의 IStatus 구현 안에 특정 상태와 관련된 모든 것을 캡슐화 할 수 있습니다.

다시 말해서 객체 지향 디자인의 관점에서 보면 UI 세부 정보 (표시 할 이미지)가 모델의 일부가된다는 것이 이상하게 느껴집니다. 반면에 뷰 모델이기 때문에 왜 안되죠? 당신은 다이 하드 OOP 및 시스템 복잡성을 가고 싶어하고 요구 사항을 보증하는 경우에는 Visitor Pattern (.NET implementation)을 고려할 수 :

interface IStatusVisitor<T>{ 
    T VisitPayedStatus<T>(PayedStatus status); 
    T PrintedStatus<T>(PrintedStatus status); 
    // ... 
} 

interface IStatus{ 
    T Accept(IStatusVisitor<T> visitor); 
} 

class PayedStatus : IStatus {  
    public T Accept(IStatusVisitor<T> visitor){ 
     return visitor.VisitPayedStatus(this); 
    } 
} 

class PrintedStatus : IStatus {  
    public T Accept(IStatusVisitor<T> visitor){ 
     return visitor.VisitPrintedStatus(this); 
    } 
} 


class InfoImageVisitor : IStatusVisitor<string>{ 

    public string VisitPayedStatus(PayedStatus status){ 
    return Links.Content.Images.payed_png; 
    } 

    public string VisitPrintedStatus(PrintedStatus status){ 
    return Links.Content.Images.not_pay_png; 
    } 

} 


<img src="@Model.Accept(new InfoImageVisitor())" alt="Status"/> 

이 방법을 당신이에 상태 클래스 밖으로 정보 이미지에 대한 모든 것을 이동 별도의 수업.

그러나 내가 말했듯이 이것은 이미 오버 엔지니어링의 한 사례로 간주 될 수 있습니다. 시스템 요구 사항에 따라 다릅니다.

일반적인주의 사항 : 디자인 패턴을 읽는 것이 좋습니다.

+0

답변 해 주셔서 감사합니다. 하지만 솔루션이 너무 많은 작업까지 쌓여 있다고 생각합니다. – user348173

+0

내가 말했듯이 상태 패턴과 방문자 패턴은 과도 할 수도 있지만 enum + T4MVC 접근 방식을 고려해야합니다. 컴파일시 오류를 잡는 데 도움이됩니다. –

0

가 나는 이것이 가장 좋은 방법은 잘 모릅니다,하지만 당신은 상태 이름으로 참고 ImageName을 정의 할 수 있습니다 다음

<div class="pull-right"> 
    <img src="@Url.Content("~/Images/" + Model.Status) + ".png""/> 
</div> 
관련 문제