2011-10-19 24 views
9

Nếu tôi đi qua HtmlAttributes vào một khuôn mẫu, như thế này:HtmlAttributes Thêm vào template

@Html.DisplayFor(m => m.FirstName, new { htmlAttributes = new { @class = "orangetxt strongtxt" } }) 

Trong mẫu của tôi, làm thế nào tôi sẽ bơm này vào HTML của tôi:

<span @ViewData["htmlAttributes"]>@Model</span> 

này hầu như làm việc, nhưng nó có một số công cụ khá kỳ lạ, vì vậy tôi giả định đây không phải là cách để đi.

Tôi nhận ra mình có thể thực hiện điều này bằng phương pháp mở rộng HtmlHelper để hiển thị phần tử HTML đầy đủ (trong trường hợp này) và chuyển thuộc tính theo cách đó, nhưng có cách để chỉ hiển thị thuộc tính thẳng vào phần tử HTML , như ví dụ trên?

Trả lời

8

Phương pháp mở rộng dưới đây sẽ cho phép tôi chuyển đổi HtmlAttributes thành một chuỗi:

public static MvcHtmlString RenderHtmlAttributes<TModel>(
     this HtmlHelper<TModel> htmlHelper, object htmlAttributes) 
    { 
     var attrbituesDictionary = new RouteValueDictionary(htmlAttributes); 

     return MvcHtmlString.Create(String.Join(" ", 
      attrbituesDictionary.Select(
       item => String.Format("{0}=\"{1}\"", item.Key, 
       htmlHelper.Encode(item.Value))))); 
    } 

Sau đó, để khiến chúng có trong thẻ, tôi chỉ có thể làm điều này: câu trả lời

<span @Html.RenderHtmlAttributes(ViewData["htmlAttributes"])>@Model</span> 
+0

Hmm tôi có thể sai ở đây, nhưng mục đích sử dụng của bạn dựa trên câu hỏi, dường như tôi sẽ không hoạt động .. có thể bạn có thể bao gồm cách bạn đang sử dụng trình trợ giúp – Ahmad

0

DisplayFor() được sử dụng để hiển thị mẫu phù hợp với loại thuộc tính.

hiển thị các mẫu là các tập tin .cshtml bên /DisplayTemplates thư mục đó lần lượt là bên trong một thư mục xem (nghĩa là bất kỳ thư mục từ đình, chia sẻ hoặc thậm chí một bộ điều khiển cụ thể).

Ví dụ.

Nếu bạn đã một String.cshtml mẫu như thế này bên /Views/Shared:

@model String 

@if (string.IsNullOrEmpty(Model)) { 
    <span>(no string)</span> 
} 
else { 
    <span>@Model</span> 
} 

Mỗi lần bạn gọi DisplayFor() cho một tài sản chuỗi:

DisplayFor(model => model.MyStringProperty); 

Nó làm cho mẫu phù hợp với giá trị của chuỗi. Bạn có thể cụ thể hơn và đặt /DisplayTemplates bên trong thư mục Chế độ xem cụ thể và chỉ những cuộc gọi từ những lượt xem đó bị ảnh hưởng bởi mẫu.


Trong trường hợp của bạn, bạn có thể cụ thể hơn và gọi DisplayFor() với mẫu cụ thể.

Giả sử bạn là mẫu cho một thuộc tính cụ thể, được gọi là MyPropertyTemplate.cshtml. Bạn sẽ gọi DisplayFor() như thế này:

DisplayFor(model => model.MyProperty, "MyPropertyTemplate"); 

Và họ, bên trong mẫu mà bạn có thể có bất cứ điều gì HTML thuộc tính mà bạn muốn.

@model MyProperty 

<span class="orangetxt strongtxt">@MyProperty.ToString()</span> 

PS: Khi không tìm thấy một mẫu Tôi đoán nó chỉ gọi model.Property.ToString() mà không html bổ sung.

FYI: EditorFor(), ví dụ: hoạt động theo cách tương tự nhưng nó sử dụng thư mục /EditorTemplates.

+1

Cảm ơn. Tôi hiểu cách thức các mẫu hoạt động, tôi chỉ cần tìm ra cách chuyển vào HtmlAttributes thành một khuôn mẫu và hiển thị chúng như trong ví dụ trên, mà không cần mã hóa chúng trong một mẫu mới. Tôi muốn họ linh hoạt hơn. –

+1

Vấn đề với các mẫu, Jerad, là nơi nào các htmlAttributes đi? Bạn có thể có một mẫu rất lớn với nhiều div và những gì không. Những gì bạn muốn làm sẽ rất tùy chỉnh và về cơ bản nó liên quan đến việc viết các phương thức HtmlHelper của riêng bạn để xuất ra với các htmlAttributes tùy chỉnh. – Buildstarted

+1

Đúng, tôi hiểu rằng với các khuôn mẫu phức tạp, thật khó để biết những gì 'htmlAttributes' sẽ được áp dụng cho. Trong trường hợp của tôi, nó sẽ luôn được áp dụng cho phần tử xung quanh giá trị mô hình ngay lập tức. Nếu tôi muốn, nói, bao gồm một tùy chọn khác để áp dụng các thuộc tính tùy chỉnh cho nhãn, sau đó tôi có thể thêm hỗ trợ cho 'labelHtmlAttributes', ví dụ. –

1

Hãy thử điều này thay vào đó,

@Html.DisplayFor(m => m.FirstName, 
       new { htmlAttributes = "class = orangetxt strongtxt"}) 

này sẽ tạo ra chuỗi, trong khi phiên bản của bạn đã làm những thứ lạ, render {} như một phần của đầu ra.

+0

Điều này là gần, nhưng vẫn không chính xác những gì tôi đang tìm kiếm. Tôi không thực sự muốn phải đối phó với tất cả các chuỗi chuyển đổi và mã hóa. Tôi thực sự đã đưa ra một phương thức mở rộng để hiển thị các thuộc tính HTML và sẽ đăng nó dưới đây. –

+0

@JeradRose - dựa trên những gì bạn có hiện tại, không có gì thay đổi ngoại trừ lệnh gọi thực tế đến Displayfor nên không có chuyển đổi và mã hóa – Ahmad

+1

Có, nhưng ở trên chỉ là một ví dụ. Tôi có thể có trường hợp các thuộc tính cần phức tạp hơn một chút và sẽ yêu cầu báo giá. Ví dụ, nếu tôi cần bao gồm 'class =" orangetxt strongtxt "id =" myId "', thì nó bắt đầu trở nên điên rồ khi sử dụng giải pháp của bạn. –

3

Jerad Rose là tốt, nhưng tôi gặp phải một vài vấn đề với nó:

  • Nó không chuyển đổi dấu gạch dưới thành dấu gạch ngang trong thuộc tính tên
  • Nó không xử lý không có giá trị thuộc tính một cách duyên dáng

Để giải quyết vấn đề đầu tiên, sử dụng HtmlHelper.AnonymousObjectToHtmlAttributes.

Dưới đây là sửa đổi của tôi về phương pháp Jerad của:

public static MvcHtmlString RenderHtmlAttributes(this HtmlHelper helper, object htmlAttributes) 
{ 
     if (htmlAttributes == null) return new MvcHtmlString(String.Empty); 
     var attrbituesDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); 
     return new MvcHtmlString(String.Join(" ", attrbituesDictionary.Select(item => string.IsNullOrEmpty((string)item.Value) ? String.Format("{0}", item.Key) : String.Format("{0}=\"{1}\"", item.Key, helper.Encode(item.Value))))); 
}