Tôi có một trang MVC3 sử dụng Razor làm công cụ xem của nó. Tôi muốn trang web của tôi có khả năng hiển thị. Hầu hết các skin có thể là tương tự, đủ để chúng có thể xuất phát từ layout master được chia sẻ.
Do đó, tôi đang xem xét thiết kế này:

Tuy nhiên, tôi muốn có thể gọi RenderSection
trong lớp dưới cùng, _Common.cshtml
và làm cho nó hiển thị một phần được xác định trong lớp trên cùng, Detail.cshtml
. Điều này không hoạt động: RenderSection
dường như chỉ hiển thị các phần được xác định lớp tiếp theo.
Tất nhiên, tôi có thể xác định từng phần trong mỗi làn da. Ví dụ, nếu _Common
cần gọi RenderSection("hd")
cho một phần được xác định trong Detail
, Tôi chỉ đặt cái này vào mỗi cái _Skin
Và nó hoạt động:
@section hd {
@RenderSection("hd")
}
Điều này dẫn đến một số mã trùng lặp (vì mỗi làn da bây giờ phải có cùng một phần này) và thường cảm thấy lộn xộn. Tôi vẫn còn mới với Razor, và có vẻ như tôi có thể thiếu một cái gì đó hiển nhiên.
Khi gỡ lỗi, tôi có thể xem danh sách đầy đủ các phần được xác định trong WebViewPage.SectionWritersStack. Nếu tôi chỉ có thể nói với RenderSection xem xét toàn bộ danh sách trước khi từ bỏ, nó sẽ tìm thấy phần tôi cần. Than ôi, SectionWritersStack là không công khai.
Ngoài ra, nếu tôi có thể truy cập vào thứ bậc của các trang bố cục và cố gắng thực hiện RenderSection trong từng ngữ cảnh khác nhau, tôi có thể tìm phần tôi cần. Tôi có thể thiếu một cái gì đó, nhưng tôi không thấy bất kỳ cách nào để làm điều này.
Có cách nào để hoàn thành mục tiêu này, ngoài phương pháp mà tôi đã vạch ra?
Đây là thực tế không thể ngày hôm nay bằng cách sử dụng API công cộng (ngoài việc sử dụng phương pháp định nghĩa lại phần). Bạn có thể có một số may mắn bằng cách sử dụng sự phản ánh riêng tư nhưng tất nhiên đó là một cách tiếp cận mong manh. Chúng tôi sẽ xem xét việc làm cho kịch bản này dễ dàng hơn trong phiên bản tiếp theo của Razor.
Trong thời gian chờ đợi, đây là một vài bài đăng trên blog mà tôi đã viết về chủ đề này:
@helper ForwardSection( string section )
{
if (IsSectionDefined(section))
{
DefineSection(section, () => Write(RenderSection(section)));
}
}
Điều này sẽ làm công việc?
Tôi không chắc chắn nếu điều này là có thể trong MVC 3 nhưng trong MVC 5 tôi có thể thành công làm điều này bằng cách sử dụng thủ thuật sau đây:
Trong ~/Views/Shared/_Common.cshtml
viết mã HTML phổ biến của bạn như:
<!DOCTYPE html>
<html lang="fa">
<head>
<title>Skinnable - @ViewBag.Title</title>
</head>
<body>
@RenderBody()
</body>
</html>
Trong ~/Views/_ViewStart.cshtml
:
@{
Layout = "~/Views/Shared/_Common.cshtml";
}
Bây giờ tất cả những gì bạn phải làm là sử dụng _Common.cshtml
như Layout
cho tất cả các giao diện. Ví dụ, trong ~/Views/Shared/Skin1.cshtml
:
@{
Layout = "~/Views/Shared/_Common.cshtml";
}
<p>Something specific to Skin1</p>
@RenderBody()
Bây giờ bạn có thể thiết lập da như bố trí của bạn trong bộ điều khiển hoặc xem dựa trên tiêu chí của bạn. Ví dụ:
public ActionResult Index()
{
//....
if (user.SelectedSkin == Skins.Skin1)
return View("ViewName", "Skin1", model);
}
Nếu bạn chạy mã trên, bạn sẽ nhận được một trang HTML với cả nội dung của Skin1.cshtml
và _Common.cshtml
Tóm lại, bạn sẽ đặt bố cục cho trang bố cục (da).
Không chắc chắn nếu điều này sẽ giúp bạn, nhưng tôi đã viết một số phương pháp mở rộng để giúp "bong bóng lên" phần từ bên trong partials, mà nên làm việc cho bố trí lồng nhau là tốt.
Đưa nội dung vào các phần cụ thể từ một khung nhìn từng phần ASP.NET MVC 3 với Công cụ Xem dao cạo
Khai báo trong bố cục / lượt xem / phần con
@using (Html.Delayed()) {
<b>show me multiple times, @Model.Whatever</b>
}
Hiển thị trong bất kỳ phụ huynh nào
@Html.RenderDelayed();
Xem liên kết câu trả lời cho nhiều trường hợp sử dụng hơn, như chỉ hiển thị một khối bị trì hoãn ngay cả khi được khai báo trong chế độ xem lặp lại, hiển thị các khối bị trì hoãn cụ thể, v.v.