2010-01-18 41 views
15

Làm cách nào để thay đổi khai báo DropDownList này để thuộc tính bị vô hiệu hóa được bật/tắt có điều kiện?Điều kiện vô hiệu hóa Html.DropDownList

<%= Html.DropDownList("Quantity", new SelectList(...), new{@disabled="disabled"} %> 

không làm việc Ví dụ:

<%= Html.DropDownList("Quantity", new SelectList(...), new{@disabled=Model.CanEdit?"false":"disabled"} %> 

tái bút: thêm một điều kiện nếu xung quanh toàn bộ tuyên bố không phải là một cách tiếp cận mong muốn :)

EDIT: dựa trên this phương pháp mở rộng từ một câu hỏi tôi đã đưa ra tiện ích sau:

public static IDictionary<string, object> Disabled (this object obj, bool disabled) 
{ 
    return disabled ? obj.AddProperty ("disabled", "disabled") : obj.ToDictionary(); 
} 

mà có thể sau đó được sử dụng như

<%= Html.DropDownList("Quantity", new SelectList(...), new{id="quantity"}.Disabled(Model.CanEdit) %> 
+0

Xin chào, tôi muốn tắt/bật menu thả xuống cho các trang cụ thể chỉ dựa trên giá trị, tôi đang đi qua nó thông qua mô hình. tôi đã cố gắng chuyển đúng/sai cho người khuyết tật nhưng nó không hoạt động. bạn có thể giúp đỡ trong số này – ravithejag

Trả lời

19

Vui lòng không viết mã spaghetti. những người giúp đỡ html đang có cho mục đích này:

public static MvcHtmlString DropDownList(this HtmlHelper html, string name, SelectList values, bool canEdit) 
{ 
    if (canEdit) 
    { 
     return html.DropDownList(name, values); 
    } 
    return html.DropDownList(name, values, new { disabled = "disabled" }); 
} 

Và sau đó:

<%= Html.DropDownList("Quantity", new SelectList(...), Model.CanEdit) %> 

Hoặc có thể bạn có thể đưa ra một cái gì đó thậm chí tốt hơn (nếu mô hình chứa các tùy chọn):

<%= Html.DropDownList("Quantity", Model) %> 

Bạn cũng sẽ nhận được tiền thưởng của việc có thêm mã kiểm thử đơn vị.

+0

Cách sử dụng trình trợ giúp làm cho đơn vị kiểm tra chế độ xem của bạn dễ dàng hơn? –

+1

Bạn không thể đơn vị kiểm tra lượt xem do tính chất của công cụ WebForms. Bạn có thể mặc dù phương pháp mở rộng thử nghiệm. Bằng cách này, chế độ xem của bạn sẽ không còn chứa logic có điều kiện để kiểm tra đơn vị. Bằng cách kiểm tra phương thức mở rộng, bạn đảm bảo rằng tất cả các chế độ xem sử dụng nó sẽ hoạt động như bạn mong đợi và có đánh dấu chính xác tùy thuộc vào thuộc tính 'CanEdit' trên mô hình của bạn. –

+0

Và mã này sẽ trông như thế nào nếu tôi cần phương thức trợ giúp với chữ ký này? 'public static string DropDownList (html HtmlHelper này, tên chuỗi, giá trị SelectList, đối tượng htmlAttributes, bool canEdit)' –

-2

tôi không biết nếu ASP.NET cung cấp một cách tiếp cận đặc biệt hợp cụ thể gọn gàng hơn, nhưng có lẽ bạn có thể làm:

<%= Html.DropDownList("Quantity", new SelectList(...), Model.CanEdit? new{@class="quantity"} : new{@class="quantity", @disabled:"disabled"}) %> 
+2

Không, bạn không thể làm điều đó. Bạn nhận được một lỗi biên dịch thời gian: "Loại biểu thức điều kiện không thể được xác định bởi vì không có chuyển đổi tiềm ẩn giữa 'AnonymousType # 1' và 'AnonymousType # 2'" –

+0

không hoạt động pls xóa câu trả lời này –

+0

Bạn sẽ cần phải thêm truyền tới anonymousTypes 'làm đối tượng' hơn nó sẽ hoạt động –

5

Một tùy chọn là tạo phiên bản tùy chỉnh Html.DropDownList có tham số bổ sung và thực hiện những gì bạn muốn ... nhưng sau đó bạn sẽ phải tạo một cái mới cho mọi loại trình trợ giúp - TextBoxFor, TextAreaFor, CheckBoxFor, vv ... và bạn vẫn phải tìm ra cách làm cho ruột của nó hoạt động.

Tôi đã chọn, để tạo một Trình trợ giúp Html để thay thế đối tượng HtmlAttributes ẩn danh thông thường kể từ đó nó sẽ tương thích với tất cả Người trợ giúp sử dụng HtmlAttributes mà không có bất kỳ công việc đặc biệt nào. Giải pháp này cũng cho phép bạn chuyển qua các Thuộc tính bổ sung như Lớp, Tên hoặc bất kỳ thứ gì bạn muốn. Nó không khóa bạn xuống chỉ để vô hiệu hóa.

Tôi đã tạo Trình trợ giúp sau - phải mất một đối tượng boolean và ẩn danh. Nếu bị vô hiệu hóa là true, nó thêm thuộc tính disabled vào đối tượng ẩn danh (thực ra là một từ điển) với giá trị "disabled", nếu không nó sẽ không thêm thuộc tính nào cả.

public static RouteValueDictionary ConditionalDisable(
    bool disabled, 
    object htmlAttributes = null) 
{ 
    var dictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); 

    if (disabled) 
     dictionary.Add("disabled", "disabled"); 

    return dictionary; 
} 


Một ví dụ về nó trong hành động:

@Html.TextBoxFor(m => m.SomeProperty,  
    HtmlHelpers.ConditionalDisable(true, new { @class = "someClass")) 


Một lợi thế rất lớn để tiếp cận này đối với tôi là nó làm việc với hầu như tất cả các HtmlHelpers MVC kể từ khi tất cả họ đều có quá tải chấp nhận một RouteValueDictionary thay vì một đối tượng vô danh.

Hãy cẩn thận:
HtmlHelper.AnonymousObjectToHtmlAttributes() sử dụng một số công việc mã ninja ưa thích để có được những điều thực hiện. Tôi không hoàn toàn chắc chắn như thế nào performant nó là ... nhưng nó là đủ cho những gì tôi sử dụng nó cho. Số dặm của bạn có thể thay đổi.

Tôi không đặc biệt thích tên của nó - nhưng tôi không thể nghĩ ra điều gì tốt hơn. Đổi tên thật dễ dàng.

Tôi cũng không thích cú pháp sử dụng - nhưng một lần nữa tôi không thể tìm ra điều gì tốt hơn. Nó không phải là khó khăn để thay đổi. Một phương pháp mở rộng trên object là một ý tưởng ... bạn sẽ kết thúc với new { @class = "someClass" }.ConditionalDisable(true) nhưng sau đó nếu bạn chỉ muốn thuộc tính vô hiệu hóa và không có bất kỳ điều gì bổ sung để thêm bạn, hãy kết thúc với một cái gì đó thô như new {}.ConditionalDisable(true); và bạn cũng kết thúc bằng một phương thức mở rộng hiển thị cho tất cả các đối tượng ... có lẽ không phải là mong muốn.

+0

Đây là câu trả lời duy nhất có khả năng xem xét để chuyển nhiều htmlAttributes hơn một và hoạt động cho tất cả HtmlHelpers. Đưa ngón cái lên. –

22

Không cần phải thêm các phương pháp helper, bạn chỉ có thể sử dụng

<%= Html.DropDownList("Quantity", new SelectList(...), IsEditable == true ? new { @disabled = "disabled" } as object : new {} as object %> 

Nếu bạn đã loại bỏ các as object mục này sẽ không làm việc vì theo mặc định new {} là một đối tượng năng động biên soạn trong thời gian chạy, do đó hai đối tượng có thể phải có cùng thuộc tính. Nhưng tham số thuộc tính Html thực sự chỉ là một đối tượng, vì vậy các động lực này có thể được sử dụng làm đối tượng để giải quyết vấn đề này. Giải pháp này thậm chí còn cho phép bạn sử dụng nhiều thuộc tính HTML, một thuộc tính tùy chọn và một thuộc tính khác không phải là class='whatever' không phải là tùy chọn. Câu trả lời của Dimitrov không hỗ trợ bất kỳ thuộc tính tùy chỉnh nào khác ngoài các thuộc tính bị tắt.

+6

+1 Mục này phải được đánh dấu là câu trả lời hay nhất –

0

gõ mạnh verison:

public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> html, 
                    Expression<Func<TModel, TProperty>> expression, 
                    IEnumerable<SelectListItem> selectList, 
                    string optionText, bool canEdit) 
    { 
     if (canEdit) 
     { 
      return html.DropDownListFor(expression, selectList, optionText); 
     } 
     return html.DropDownListFor(expression, selectList, optionText, new { disabled = "disabled" }); 
    } 
2
@bool IsEditable=true; 

@if (IsEditable) 
{ 
    Html.DropDownListFor(m => m, selectList); 
} 
else 
{ 
    Html.DropDownListFor(m => m, selectList, new { disabled = "disabled" }) 
} 
Các vấn đề liên quan