Chương 22 Templated Helper Method Những HTML helper trong chương trước, chẳng hạn như Html.CheckBoxFor và Html.TextBoxFor, tạo ra một loại element cụ thể, tôi phải quy định trước loại element được sử dụng cho model và cập nhật view một cách thủ công nếu thuộc tính thay đổi. Trong chương này, tôi sẽ chỉ cho bạn templated helper method, tôi chỉ cần khai báo các thcuộ tính và để cho MVC Framework tìm ra HTML element phù hợp. Đây là cách tiếp cận linh hoạt hơn trong việc hiển thị dữ liệu, mặc dù nó đòi hỏi cao khi thiết lập. Bảng 22-1 tóm tắt cho chương này. Bảng 22-1. Tòm tắt chương Vấn đề Tạo element có thể được sử dụng để chỉnh sửa thuộc tính model Tạo label read-only đại diện cho thuộc tính của tính mô hình Tạo các element từ một đối tượng model hoàn chỉnh
Giải quyết Helper Html.Editor và Html.EditorFor Helper Html.Label và Html.Display Helper DisplayForModel, EditorForModel và LabelForModel Giấu một phần tử khỏi người dùng Áp dụng thuộc tính hoặc không cho phép chỉnh sửa khi HiddenInput cho trường tạo các element bằng cách sử dụng
một whole-model helper Tạo label sẽ được sử dụng để hiển Thuộc tính DisplayName và thị các thuộc tính model Display
Ví dụ 1-5, 18 6-8 9-10
11-12
13
Tùy chỉnh cách mà các thuộc tính của model được hiển thị Tùy chỉnh template được sử dụng để hiển thị thuộc tính của model Tạo model metadata tách biệt với model type Thay đổi element được tạo ra từ thcuộ tính của model
Thuộc tính DataType
14
Thuộc tính UIHint
15
Tạo một lớp buddy và sử dụng thuộc tính MetadataType Tạo một custom template
16-17 19-22
Chuẩn bị Project mẫu Trong chương này ta sẽ tiếp tục sử dụng project HelperMethod trong Chương 21. Trong project đó, tôi tạo ra một class model Person như trong Ví dụ 22-1. Ví dụ 22-1. Nội dung của file Person.cs using System; namespace HelperMethods.Models { public class Person { public int PersonId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime BirthDate { get; set; } public Address HomeAddress { get; set; } public bool IsApproved { get; set; } public Role Role { get; set; } } public class Address { public string Line1 { get; set; } public string Line2 { get; set; }
public string City { get; set; } public string PostalCode { get; set; } public string Country { get; set; } } public enum Role { Admin, User, Guest } }
Project chứa một Home controller đơn giản mà tôi sử dụng để hiển thị form và nhận form trả về. Bạn có thể xem HomeController trong Ví dụ 22-2.
Ví dụ 22-2. Nội dung của file HomeController.cs using System.Web.Mvc; using HelperMethods.Models; namespace HelperMethods.Controllers { public class HomeController : Controller { public ActionResult Index() { ViewBag.Fruits = new string[] { "Apple", "Orange", "Pear" }; ViewBag.Cities = new string[] { "New York", "London", "Paris" }; string message = "This is an HTML element: <input>";
Đây là hai action method CreatePerson tôi sẽ sử dụng trong chương này, cả hai được dùng cho file view /Views/Home/CreatePerson.cshtml. Trong Ví dụ 22-3, bạn có thể xem view CreatePerson ở chương trước, có một sự thay đổi đơn giản.
Tôi thêm một dòng in đậm. Theo mặc định, các helper method sẽ thêm dữ liệu của thuộc tính cho HTML element mà nó tạo ra để hỗ trợ validate form (ứng dụng SportsStore). Nhưng tơi không muốn sử dụng những thuộc tính đó trong chương này, nên tôi đã sử dụng hàm Html.EnableClientValidation để vô hiệu hóa chúng trong view CreatePerson. Các tính năng client validate vẫn được kích hoạt cho phần còn lại của ứng dụng và tôi sẽ giải thích làm thế nào validation làm việc (bao gồm mục đích của thuộc tính data) trong Chương 25.
Sử dụng Templated Helper Method Các templated helper method đầu tiên mà tôi sẽ dùng là Html.Editor và
Html.EditorFor. Các Editor method nhận một tham số string để chỉ ra thuộc tính nào sẽ được chỉnh sửa. Các helper sẽ tìm kiếm (tôi đã mô tả trong chương 20) để xác định vị trí một thuộc tính tương ứng trong view bag và view model. Phương pháp EditorFor cho phép bạn sử dụng một biểu thức lambda để xác định một thuộc tính của model mà bạn muốn dùng element để chỉnh sửa nó.
Trong Ví dụ 22-4, bạn có thể thấy tôi đã áp dụng cả hai helper method Editor và EditorFor trong view CreatePerson. Như tôi đã đề cập trong chương trước, tôi thích sử dụng strongly typed helper vì chúng làm giảm nguy cơ gây ra lỗi khi đánh nhầm tên thuộc tính, nhưng tôi đã sử dụng cả hai loại trong bảng ví dụ này chỉ ra rằng bạn có thể kết hợp chúng nếu như bạn thấy phù hợp. Ví dụ 22-4. Sử dụng helper method Editor và EditorFor trong file CreatePerson.cshtml @model HelperMethods.Models.Person @{ ViewBag.Title = "CreatePerson"; Layout = "/Views/Shared/_Layout.cshtml"; Html.EnableClientValidation(false); }
Các HTML element được tạo ra bằng các hàm Editor và EditorFor đều giống nhau. Sự khác biệt chỉ là cách mà bạn chỉ ra những thuộc tính mà các editor element sẽ tạo ra để chỉnh sửa chúng. Bạn có thể xem kết quả của những thay đổi bằng cách chạy ứng dụng ví dụ và điều hướng đến URL /Home/CreatePerson, như trong hình 22-1.
Hình 22-1. Sử dụng các method helper Editor và EditorFor trong một form Ngoài việc bổ sung thuộc tính BirthDate, nó không khác với form mà tôi đã tạo ra trong Chương 21. Tuy nhiên, có một sự thay đổi khá đáng kể, mà bạn có thể thấy nếu bạn sử dụng một trình duyệt khác. Trong hình 22-2, bạn có thể thấy cùng một URL hiển thị trong trình duyệt Opera.
Hình 22-2. Hiển thị một form được tạo ra bằng cách sử dụng helper method Editor và EditorFor. Chú ý rằng các element cho các thuộc tính PersonId và BirthDate sẽ trông khác. Các element PersonId có spinner arrow (cho phép bạn tăng và giảm các giá trị) và các element BirthDate được hiển thị với một bảng chọn ngày. HTML5 định nghĩa của các input element khác nhau có thể được sử dụng để chỉnh sửa các loại dữ liệu phổ biến, chẳng hạn như số và ngày tháng. Method Helper và HelperFor sử dụng loại thuộc tính tôi muốn chỉnh sửa để chọn input element. Bạn có thể thấy điều này trong Ví dụ 22-5, HTML được tạo ra cho form. Ví dụ 22-5. Các HTML element tạo bởi người helper method Editor và EditorFor <!DOCTYPE html>
Các thuộc tính type xác định được loại input elemnt sẽ được hiển thị bởi trình duyệt. Các helper method đã quy định các type number và datetime cho PersonId và text cho BirthDate, text là mặc định cho các thuộc tính khác. Lý do mà chúng ta chỉ nhìn thấy những type này ở Opera là vì các tính năng HTML5 vẫn không được hỗ trợ rộng rãi, ngay cả trong các phiên bản mới nhất của Internet Explorer và Chrome.
Mẹo. Hầu hết các bộ công cụ giao diện web đều có date picker, bạn có thể sử dụng chúng thay vì dựa vào các HTML5 input element. Nếu bạn chưa có một bộ công cụ như vậy cho dự án, tôi đề nghị bạn bắt đầu với jQuery UI (), là một bộ công cụ mã nguồn mở, được xây dựng trên jQuery. Bạn có thể thấy rằng bằng cách sử dụng các templated helper method tôi đã có thể chỉnh các element từ hình thức đến nội dung, mặc dù không phải là một cách quá hữu ích, một phần vì không phải tất cả các trình duyệt có thể hiển thị các HTML5 input element và một phần vì một số thuộc tính, chẳng hạn như Role, không được hiển thị tốt. Tôi sẽ cho bạn thấy làm thế nào để cung cấp cho MVC Framework thông tin bổ sung để cải thiện HTML mà các helper method tạo ra. Nhưng trước hết hãy xem những templated helper method khác. Bạn có thể xem toàn bộ các helper method trong Bảng 22-2 và tôi sẽ giải thích các helper trong phần tiếp theo. Bảng 22-2. Các MVC Templated HTML Helper Helper Display
Ví dụ
Miêu tả Html.Display("FirstName") Tạo một read-only view cho các thuộc tính mô hình, chọn HTML element dựa trên type của thuộc
tính và metadata Phiên bản strongly typed của DisplayFor Html.DisplayFor(x => x.FirstName) helper trên Html.Editor("FirstName") Tạo một editor cho các thuộc tính Editor mô hình, chọn HTML element dựa trên type của thuộc tính và metadata Phiên bản strongly typed của EditorFor Html.EditorFor(x => x.FirstName) helper trên Html.Label("FirstName") Label Tạo một HTML <label> element cho thuộc tính của model Html.LabelFor(x => Phiên bản strongly typed của LabelFor x.FirstName) helper trên
Tạo Label và Display Element Để chỉ cho bạn các helper method khác, tôi sẽ thêm một action method và view mới để tạo một read-only view cho dữ liệu được submit từ form. Trước tiên, tôi sẽ làm mới HttpPost của action CreatePerson trong bộ Home controller, như trong Ví dụ 22-6.
Ví dụ 22-6. Tạo một view khác trong file HomeController.cs using System.Web.Mvc; using HelperMethods.Models; namespace HelperMethods.Controllers { public class HomeController : Controller { public ActionResult Index() { ViewBag.Fruits = new string[] { "Apple", "Orange", "Pear" }; ViewBag.Cities = new string[] { "New York", "London", "Paris" }; string message = "This is an HTML element: <input>"; return View((object)message); } public ActionResult CreatePerson() { return View(new Person()); } [HttpPost] public ActionResult CreatePerson(Person person) { return View("DisplayPerson", person); } } }
Tôi thêm file view DisplayPerson.cshtml vào thư mục /Views/Home, xem nội dung của tập tin này trong Ví dụ 22-7. Ví dụ 22-7. Nội dung của file DisplayPerson.cshtml
Bạn có thể thấy view mới khi chạy ứng dụng, điều hướng đến URL
/Home/CreatePerson, điền vào form và nhấp vào nút Submit. Kết quả được thể hiện trong hình 22-3 và bạn có thể thấy có một số thay đổi, vì helper Label và LabelFor chỉ sử dụng tên thuộc tính làm nội dung cho label.
Hình 22-3. Sử dụng helper để tạo ra một read-only view của các đối tượng Person Bạn có thể nhìn thấy kết quả của những helper method trong Ví dụ 22-8. Chú ý rằng mặc định thì các method Display và DisplayFor này không tạo ra HTML element. Nó chỉ hiển thị giá trị của các thuộc tính.
Ví dụ 22-8. HTML được tạo ra từ view DisplayPerson <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>DisplayPerson</title> <style type="text/css"> label { display: inline-block; width: 100px;} .dataElem { margin: 5px;} </style> </head> <body>
Mặc dù những helper có thể có vẻ không hữu ích vào lúc này, nhưng tôi sẽ chỉ cho bạn cách cải thiện trong thời gian ngắn.
Sử dụng Whole-Model Templated Helpers Tôi đã sử dụng templated helper cho một thuộc tính duy nhất, nhưng các MVC Framework hiểu rằng helper hoạt động trên toàn bộ đối tượng, một quá trình được gọi là scaffolding. Những scaffolding helper có sẵn trong Bảng 22-3.
Miêu tả DisplayForModel Html.DisplayForModel() Tạo một read-only view cho toàn bộ đối tượng model EditorForModel Html.EditorForModel() Tạo các editor element cho toàn bộ đối tượng model Html.LabelForModel() LabelForModel Tạo một HTML <label> liên kết với đối tượng model Mẹo. scaffolding này không giống với cái được Microsoft thêm vàoVisual Studio để tạo ra các thành phần MVC như controller và view, nhưng ý tưởng cơ bản thì như nhau trong đó kết quả được tạo ra dựa trên kiểu dữ liệu. Trong trường hợp của Visual Studio, kết quả từ scaffolding là một class hoặc tập tin Razor và đầu ra của templated helper là HTML. Trong Ví dụ 22-9, bạn có thể thấy cách sử dụng các helper method LabelForModel và EditorForModel để đơn giản hóa view CreatePerson.cshtml. Ví dụ 22-9. Sử dụng các Scaffolding Helper Method trong file CreatePerson.cshtml @model HelperMethods.Models.Person @{ ViewBag.Title = "CreatePerson"; Layout = "/Views/Shared/_Layout.cshtml"; Html.EnableClientValidation(false); }
CreatePerson: @Html.LabelForModel()
@using(Html.BeginRouteForm("FormRoute", new {}, FormMethod.Post, new { @class = "personClass", data_formType="person"})) { @Html.EditorForModel() <input type="submit" value="Submit" /> }
Bạn có thể thấy kết quả của scaffolding helper trong hình 22-4. Một lần nữa, helper cho ra kết quả không như mong đợi. Helper LabelForModel đã tạo ra một label không tốt. Mặc dù có nhiều thuộc tính của các đối tượng model được hiển thị hơn những cái tôi đã tạo bằng tay trong ví dụ trước, nhưng không phải tất cả mọi thứ đều được hiển thị (chẳng hạn như thuộc tính Address) và những gì hiển thị không phải lúc nào cũng hữu ích (như các thuộc tính Role, select element sẽ tốt hơn input element).
Hình 22-4. Sử dụng scaffolding helper để tạo ra một editor cho các đối tượng model Person Một phần của vấn đề là các HTML mà những scaffolding helper tạo ra không tương ứng với CSS mà tôi định nghĩa trong file /Views/Shared/_Layout.cshtml trong chương trước. Dưới đây là một ví dụ của HTML được tạo ra để chỉnh sửa thuộc tính FirstName: ... <div class="editor-label"> <label for="FirstName">FirstName</label> </div> <div class="editor-field"> type="text" value="" /> </div> ...
Tôi có thể làm gọn view bằng cách dùng scaffolding helper để thêm CSS vào các input và div bằng thuộc tính class. Trong Ví dụ 22-10, bạn có thể thấy những thay đổi tôi thực hiện cho các tập tin _Layout.cshtml.
Hình 22-5. Kết quả của việc thêm style cho element bằng scaffolding helper method.
Sử dụng Model Metadata Như bạn đã thấy, những templated helper không có kiến thức về các ứng dụng và các model data type, vì vậy nó tạo ra HTML không như ta mong muốn. Cần phải nâng cao chất lượng đầu ra của các helper method trước khi sử dụng. Không thể đổ lỗi cho templated helper trong trường hợp này; HTML được tạo ra dựa trên dự đoán tốt nhất về những gì tôi muốn. Đây là vấn đề gặp với tất cả các scaffolding. May mắn thay, những templated helper có thể được cải thiện bằng cách sử dụng model metadata để cung cấp hướng dẫn làm thế nào để xử lý các loại model. Metadata được dùng bằng cách sử dụng thuộc tính C#, các thuộc tính và các giá trị tham số cung cấp hướng dẫn cho view helper. Metadata được áp dụng cho class model, mà các helper method sử dụng khi tạo ra HTML. Trong các phần sau, tôi chỉ cho bạn cách sử dụng metadata để hỗ trợ cho những helper trong việc tạo ra label, editor, và hiển thị.
Sử dụng Metadata cho Control Editing và Visibility Trong class Person, thuộc tính PersonId không thể xem hoặc chỉnh sửa. Hầu hết các class model có ít nhất một thuộc tính như vậy, thường liên quan đến việc lưu trữ, là một khóa chính được quản lý bởi một cơ sở dữ liệu quan hệ (ví dụ ứng dụng SportsStore). Ta có thể sử dụng các thuộc tính HiddenInput, để helper tạo ra một input ẩn. Bạn có thể trong Ví dụ 22-11. Ví dụ 22-11. Sử dụng thuộc tính HiddenInput trong file Person.cs using System; using System.Web.Mvc; namespace HelperMethods.Models { public class Person { [HiddenInput] public int PersonId { get; set; } public string FirstName { get; set; }
public string LastName { get; set; } public DateTime BirthDate { get; set; } public Address HomeAddress { get; set; } public bool IsApproved { get; set; } public Role Role { get; set; } } / / ... other types omitted for brevity... }
Khi thuộc tính này đã được áp dụng, những helper Html.EditorFor và Html.EditorForModel sẽ tạo một read-only view dựa trên thuộc tính trang trí, như thể hiện trong hình 22-6.
Hình 22-6. Tạo một read-only field trong editor Giá trị của thuộc tính PersonId được hiển thị, nhưng người dùng không thể chỉnh sửa nó. HTML được tạo ra như sau: ... <div class="editor-field"> 0 <input id="PersonId" name="PersonId" type="hidden" value="0" /> </div> ...
Giá trị của thuộc tính (0 trong trường hợp này) được tạo cứng, nhưng helper cũng thêm một input ẩn cho thuộc tính, để đảm bảo rằng mọi giá trị của form sẽ được submit. Xem them về model binding trong Chương 24 và model validation trong Chương 25. Nếu tôi muốn ẩn một thuộc tính hoàn toàn, sau đó tôi có thể thiết lập giá trị của thuộc tính DisplayValue thành false, như trong Ví dụ 22-12. Ví dụ 22-12. Sử dụng thuộc tính HiddenInput để ẩn một trường trong File
Person.cs ... public class Person { [HiddenInput(DisplayValue = false)] public int PersonId { get; set; } public string FirstName { get; set; }
Khi tôi sử dụng các helper Html.EditorForModel trên một đối tượng Person, một input ẩn sẽ được tạo ra để các giá trị của PersonId sẽ được gửi khi submit form, nhưng các label và value sẽ bị bỏ qua. Nó tác dụng giấu PersonId khỏi người sử dụng, như trong Hình 22-7.
Hình 22-7. Ẩn thuộc tính của đối tượng model
Vẫn có thể tạo ra các input ẩn cho PersonId bằng cách sử dụng các helper Html.EditorFor, như thế này: ... @Html.EditorFor(m => m.PersonId) ...
Các thuộc tính HiddenInput sẽ được phát hiện, và nếu DisplayValue là true, thì HTML sau đây được tạo ra: ... <input id="PersonId" name="PersonId" type="hidden" value="1" /> ...
LOẠI MỘT TRƯỜNG RA KHỎI SCAFFOLDING Để loại trừ hoàn toàn một trường khỏi HTML, ta sử dụng thuộc tính ScaffoldColumn. Trong khi thuộc tính HiddenInput có giá trị trong một input ẩn, thuộc tính ScaffoldColumn có thể loại bỏ một trường khỏi quá trình scaffolding. Dưới đây là một ví dụ về các thuộc tính được sử dụng: ... [ScaffoldColumn(false)] public int PersonId { get; set; } ...
Khi scaffolding helper thấy các thuộc tính ScaffoldColumn như thế này, nó sẽ bỏ qua trường đó hoàn toàn; không có input ẩn được tạo ra, và không có hiện diện của thuộc tính này được tạo trong HTML. HTML được tạo ra sẽ giống như khi sử dụng các thuộc tính HiddenInput, nhưng không có giá trị của trường được trả về khi submit. Điều này có ảnh hưởng đến model binding, trong Chương 24. Thuộc tính ScaffoldColumn không hoạt động trên helper đơn, như EditorFor. Nếu tôi gọi @Html.EditorFor (m => m.PersonId) trong một view, một editor cho các
trường PersonId sẽ được tạo ra, ngay cả khi thuộc tính ScaffoldColumn tồn tại.
Sử dụng Metadata cho Label Theo mặc định, các Label, LabelFor, LabelForModel, và helper EditorForModel sử dụng tên thuộc tính như nội dung cho label nó tạo ra. Ví dụ, nếu tôi tạo một label bằng cách này: ... @Html.LabelFor(m => m.BirthDate) ...
Kết quả sẽ là: ... <label for="BirthDate">BirthDate</label> ...
Tất nhiên, tên của thuộc tính thường không hợp để hiển thị cho người sử dụng. Vậy nên, tôi có thể áp dụng thuộc tính DisplayName từ namespace System.ComponentModel.DataAnnotations, đặt giá trị tôi muốn hiển thị thông qua thuộc tính Name. Ví dụ 22-13, thuộc tính này áp dụng cho lớp Person.
Ví dụ 22-13. Sử dụng thuộc tính DisplayName để tạo một Label trong file Person.cs using System; using System.Web.Mvc; using System.ComponentModel.DataAnnotations; using System.ComponentModel; namespace HelperMethods.Models { [DisplayName("New Person")]
public class Person { [HiddenInput(DisplayValue = false)] public int PersonId { get; set; } [Display(Name = "First")] public string FirstName { get; set; } [Display(Name = "Last")] public string LastName { get; set; } [Display(Name = "Birth Date")] public DateTime BirthDate { get; set; } public Address HomeAddress { get; set; } [Display(Name = "Approved")] public bool IsApproved { get; set; } public Role Role { get; set; } } // ...other types omitted for brevity... }
Khi label helper tạo một label cho trường BirthDate, nó sẽ tìm thuộc tính Display và sử dụng giá trị của thuộc tính Name làm text của label: ... <label for="BirthDate">Birth Date</label> ...
Những helper cũng nhận ra thuộc tính DisplayName, có thể được tìm thấy trong namespace System.ComponentModel. Thuộc tính này có lợi thế là có thể được áp dụng cho class, cho phép ta sử dụng các helper Html.LabelForModel. Bạn có thể xem các sử dụng thuộc tính này cho class Person trong ví dụ. (Ta có thể áp dụng thuộc tính DisplayName cho mọi trường, nhưng tôi thường sử dụng thuộc tính này cho các model class, chỉ là thói quen.) Bạn có thể thấy tác dụng của Display and
DisplayName trong hình 22-8.
Sử dụng Metadata cho các Data Value Tôi cũng có thể sử dụng metadata để hỗ trợ việc hiển thị thuộc tính của model. Tôi có thể sử dụng để trường BirthDate từ việc hiển thị cả giờ sang chỉ hiện thỉ ngày. Tôi kiểm soát cách dữ liệu được hiển thị bằng cách sử dụng thuộc tính DataType, bạn có thể thấy trong Ví dụ 22-14. Ví dụ 22-14. Áp dụng thuộc tính DataType trong file Person.cs ... [DisplayName("New Person")] public class Person { [HiddenInput(DisplayValue = false)] public int PersonId { get; set; } [Display(Name = "First")] public string FirstName { get; set; } [Display(Name = "Last")] public string LastName { get; set; } [Display(Name = "Birth Date")] [DataType(DataType.Date)] public DateTime BirthDate { get; set; } public Address HomeAddress { get; set; } [Display(Name = "Approved")] public bool IsApproved { get; set; } public Role Role { get; set; } } ...
Thuộc tính DataType nhận một giá trị từ DataType enum làm tham số. Trong ví dụ tôi đã dùng DataType.Date, để templated helper tạo ra giá trị của trường BirthDate chỉ có ngày mà không có giờ, như trong hình 22-9.
Hình 22-9. Sử dụng thuộc tính DataType để kiểm soát việc hiển thị giá trị DateTime Mẹo. Sự thay đổi rõ rệt khi sử dụng một trình duyệt Web có hỗ trợ input HTML5 tốt. Bảng 22-4 Mô tả các giá trị hữu ích nhất của DataType enumeration. Bảng 22-4. Các giá trị của DataType Enumeration Giá trị DateTime
Miêu tả Hiển thị ngày tháng và thời gian (đây là mặc định cho System.DateTime) Hiển thị phần ngày Date Hiển thị phần thời gian Time Hiển thị một dòng chữ Text Hiển thị số điện thoại PhoneNumber MultilineText Gán giá trị vào một textarea Hiển thị dữ liệu đã được dấu Password Url Hiển thị dữ liệu như URL (sử dụng HTML element a) EmailAddress Hiển thị dữ liệu như địa chỉ e-mail (bằng cách sử dụng một
element a với một mailto href) Ảnh hưởng của các giá trị này phụ thuộc vào loại trường liên quan và các helper đang được sử dụng. Ví dụ, giá trị MultilineText sẽ làm helper thay vì tạo ra editor cho trường thì sẽ tạo một textarea, nhưng nó sẽ bị bỏ qua bởi display
helper. Các textarea cho phép người dùng chỉnh sửa một giá trị, nhưng không có có tác dụng nhiều khi dữ liệu hiển thị trong read-only form. Tương tự, giá trị Url chỉ có hiệu quả chỉ trên những display helper tạo ra HTML element a để tạo liên kết.
Sử dụng Metadata để chọn một Display Template Như tên gọi của chúng, những templated helper sử dụng display template để tạo HTML. Các template được sử dụng dựa vào loại trường được xử lý và loại helper đang được sử dụng. Tôi có thể sử dụng thuộc tính UIHint để tuỳ chỉnh template được sử dụng để tạo HTML cho một trường, như trong Ví dụ 22-15. Ví dụ 22-15. Sử dụng thuộc tính UIHint trong file Person.cs ... [DisplayName("New Person")] public class Person { [HiddenInput(DisplayValue = false)] public int PersonId { get; set; } [Display(Name = "First")] [UIHint("MultilineText")] public string FirstName { get; set; } [Display(Name = "Last")] public string LastName { get; set; } [Display(Name = "Birth Date")] [DataType(DataType.Date)] public DateTime BirthDate { get; set; }
public Address HomeAddress { get; set; } [Display(Name = "Approved")] public bool IsApproved { get; set; } public Role Role { get; set; } } ...
Trong ví dụ trên, tôi đã sử dụng MultilineText template, nó sẽ tạo một textarea cho FirstName khi được sử dụng với một trong những editor helper, như EditorFor hoặc EditorForModel. Bảng 22-5 cho thấy các thiết lập cho các template tích hợp sẵn của MVC Framework. Bảng 22-5. Các MVC Framework View Template Giá trị Boolean
Chỉnh sửa Tạo checkbox, khi null thì tạo thêm một lựa chọn Not Set
Hiển thị Read-only, thêm thuộc tính disabled
Collection
Decimal DateTime Date
EmailAddress
Tạo template thích hợp cho mỗi phần tử trong một chuỗi IEnumerable. Các phần tử không cần phải cùng loại. Tạo một textbox input một dòng Tạo một textbox input hiển thị cả ngày và giờ có type là datetime Tạo một textbox input hiển thị ngày có type là date Gán giá trị vào một textbox input
Giống bên trái
Tạo một giá trị Tạo một giá trị ngày giờ Tạo một giá trị ngày
Sử dụng thẻ a và thuộc tính href Tại giá trị và một HiddenInput Tạo một input ẩn input ẩn Html Gán giá trị vào một textbox input Tạo link bằng thẻ a Tạo giá trị MultilineText Gán giá trị vào một textarea Tạo giá trị
Number Tạo một input có type là number Xem thêm sau bảng này Xem thêm sau bảng Object này Password Tạo một textbox input có giá trị bị Tạo giá trị không bị giấu giấu nhưng cho phép chỉnh sửa Tạo giá trị String Tạo một textbox input Tạo giá trị Text Tạo một textbox input Tạo giá trị Tel Tạo một input có type là tel Time Tạo một textbox input hiển thị giờ Tạo một giá trị giờ có type là time Url Tạo một textbox input Tạo thẻ a, nội dung và giá trị của href đều được gán Cảnh báo. Chú ý khi sử dụng các thuộc tính UIHint. Sẽ có exception khi sử dụng template không thể hoạt động trên trường được áp dụng, ví dụ, áp dụng Boolean template cho một trường string.
Các Object template là một trường hợp đặc biệt. Đó là các template được sử dụng bởi những scaffolding helper để tạo ra HTML cho một view model. Template này