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.. Tạo element có thể được sử dụng để
Trang 1Trong 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
Tạo element có thể được sử dụng
để chỉnh sửa thuộc tính model
Helper Html.Editor và Html.EditorFor
1-5, 18
Tạo label read-only đại diện cho
thuộc tính của tính mô hình
Helper Html.Label và Html.Display
6-8
Tạo các element từ một đối tượng
model hoàn chỉnh
Helper DisplayForModel, EditorForModel và
LabelForModel
9-10
Giấu một phần tử khỏi người dùng
hoặc không cho phép chỉnh sửa khi
tạo các element bằng cách sử dụng
một whole-model helper
Áp dụng thuộc tính HiddenInput cho trường
11-12
Tạo label sẽ được sử dụng để hiển
thị các thuộc tính model
Thuộc tính DisplayName và Display
13
Trang 2Tù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
Tạo một lớp buddy và sử dụng thuộc tính MetadataType
16-17
Thay đổi element được tạo ra từ
thcuộ tính của model
Tạo một custom template 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
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 ; }
Trang 4Ví dụ 22-2 Nội dung của file HomeController.cs
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);
Trang 5Ví dụ 22-3 Nội dung của file CreatePerson.cshtml
@using (Html.BeginRouteForm("FormRoute", new { }, FormMethod.Post,
new { @class = "personClass", data_formType = "person" })) {
< div class ="dataElem">
< label > PersonId </ label >
@Html.TextBoxFor(m => m.PersonId)
</ div >
< div class ="dataElem">
< label > First Name </ label >
@Html.TextBoxFor(m => m.FirstName)
</ div >
< div class ="dataElem">
< label > Last Name </ label >
@Html.TextBoxFor(m => m.LastName)
</ div >
< div class ="dataElem">
< label > Role </ label >
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ó
Trang 6Trong 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
@using(Html.BeginRouteForm("FormRoute", new {}, FormMethod.Post,
new { @class = "personClass", data_formType="person"})) {
< div class ="dataElem">
< label > PersonId </ label >
@Html.Editor("PersonId")
</ div >
< div class ="dataElem">
< label > First Name </ label >
@Html.Editor("FirstName")
</ div >
< div class ="dataElem">
< label > Last Name </ label >
@Html.EditorFor(m => m.LastName)
</ div >
< div class ="dataElem">
< label > Role </ label >
@Html.EditorFor(m => m.Role)
</ div >
< div class ="dataElem">
< label > Birth Date </ label >
Trang 7Hì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
Trang 8Hì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
EditorFor
< !DOCTYPE html >
Trang 9< html >
< head >
< meta charset ="utf-8" />
< meta name ="viewport" content ="width=device-width" />
< title > CreatePerson </ title >
< style type ="text/css">
label { display: inline-block; width: 100px;}
< form action ="/app/forms/Home/CreatePerson" class ="personClass"
data-formType ="person" method ="post">
< div class ="dataElem">
< label > PersonId </ label >
< input class ="text-box single-line" id ="PersonId" name ="PersonId"
type ="number" value ="0" />
</ div >
< div class ="dataElem">
< label > First Name </ label >
< input class ="text-box single-line" id ="FirstName"
name ="FirstName"
type ="text" value ="" />
</ div >
< div class ="dataElem">
< label > Last Name </ label >
< input class ="text-box single-line" id ="LastName" name ="LastName"
type ="text" value ="" />
</ div >
< div class ="dataElem">
< label > Role </ label >
< input class ="text-box single-line" id ="Role" name ="Role"
type ="text" value ="Admin" />
</ div >
< div class ="dataElem">
< label > Birth Date </ label >
< input class ="text-box single-line" id ="BirthDate"
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
Trang 10Mẹ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 (http://jqueryui.com), 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
Display 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
DisplayFor Html.DisplayFor(x =>
x.FirstName) Phiên bản strongly typed của
helper trên Editor Html.Editor("FirstName") Tạo một editor 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
EditorFor Html.EditorFor(x =>
x.FirstName) Phiên bản strongly typed của
helper trên Label Html.Label("FirstName") Tạo một HTML <label>
element cho thuộc tính của model LabelFor Html.LabelFor(x =>
x.FirstName)
Phiên bản strongly typed của helper trên
Trang 11Tạ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í
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);
Trang 12< div class ="dataElem">
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
Trang 13Ví 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;}
< div class ="dataElem">
< label for ="PersonId"> PersonId </ label >
100
</ div >
< div class ="dataElem">
< label for ="FirstName"> FirstName </ label >
Adam
</ div >
< div class ="dataElem">
< label for ="LastName"> LastName </ label >
Freeman
</ div >
< div class ="dataElem">
< label for ="Role"> Role </ label >
Admin
</ div >
< div class ="dataElem">
< label for ="BirthDate"> BirthDate </ label >
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
Trang 14Bảng 22-3 Các MVC Scaffolding Templated Helper Method
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 LabelForModel Html.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
@using(Html.BeginRouteForm("FormRoute", new {}, FormMethod.Post,
new { @class = "personClass", data_formType="person"})) {
Trang 15Hì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">
< input class ="text-box single-line" id ="FirstName" name ="FirstName"
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
Trang 16Ví dụ 22-10 Thay đổi CSS được định nghĩa trong file _Layout.cshtml
< !DOCTYPE html >
< html >
< head >
< meta charset ="utf-8" />
< meta name ="viewport" content ="width=device-width" />
< title > @ViewBag.Title </ title >
< style type ="text/css">
label { display: inline-block; width: 100px; }
div.dataElem { margin: 5px; }
h2 > label { width: inherit; }
.editor-label, editor-field { float: left; margin-top: 10px;}
.editor-field input { height: 20px; }
.editor-label { clear: left;}
.editor-field { margin-left: 10px; }
input[type=submit] { float: left; clear: both; margin-top: 10px; }
.column { float: left; margin: 10px;}
Kết quả như trong hình 22-5
method
Trang 17Sử 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
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
}