爲了您的擔憂PageData
:
PageData
對象(你在自己的系統(「ArticlePage」,「末頁」或其他人)創建的所有衍生工具在內存中緩存相比「FooBar的風格」的教程。但是在現實生活中,您可以輕鬆地處理數百個類,以便在現代服務器上加載單個頁面,並添加一些輸出緩存或其他緩存解決方案,並且在實踐中成爲一個非問題。 Get<T>(...)
和GetChildren<T>(...)
對於每一個請求都是非常好的。
確實,它具有負載的屬性,但對於一個給定的頁面對象,最好擁有「一個真相源」,而不是對整個站點中的每一個用法都進行自定義查詢。突然間,你會想要一些你定義的文本屬性。或訪問訪問控制列表。或者檢查它的內容類型。或編輯並保存。
例如:在一個簡單的菜單,你可能都希望它的名字,可能是某種形式的「介紹」,「節選」或「MainIntro」屬性,這是ContentLink
(創建<a href=...>
實際值),也,您通常會處理特定類型的項目,而不是基類,這可以打開更多由您自己定義的屬性。
所以沒有,這是沒有必要的,也沒有矯枉過正。這是常見的做法,它的工作原理。如果你不想在編輯時看到所有的屬性,你可以簡單地把它們作爲IContent
。但請注意,它背後的實現仍然是PageData
對象(或者是您正在檢索的實際頁面類型的運行時生成的代理類)。
除此之外:
- 你不應該把代碼加載這樣的觀點。程序邏輯屬於控制器或其他類。這與Episerver無關,更多的是通用的最佳實踐。
- 你應該避免訪問
DataFactory
,並且相當(無論是作爲一個構造函數的參數,或者通過ServiceLocator.Current.GetInstance<IContentLoader>
通過依賴注入獲取IContentLoader
這裏有一個靈活且簡單的方法麪包屑:
創建一個文件像HtmlHelperExtensions.cs
,其中包含:
public static IHtmlString BreadCrumbs(
this HtmlHelper helper,
ContentReference currentPage,
Func<MenuItemViewModel, HelperResult> itemTemplate = null,
bool includeCurrentPage = true,
bool requireVisibleInMenu = true,
bool requirePageTemplate = true)
{
itemTemplate = itemTemplate ?? GetDefaultItemTemplate(helper);
Func<IEnumerable<PageData>, IEnumerable<PageData>> filter = GetFilter(requireVisibleInMenu, requirePageTemplate);
var menuItems = new List<MenuItemViewModel>();
var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
var currentPageData = contentLoader.Get<PageData>(currentPage);
ContentReference parentLink = currentPageData.ParentLink;
if (includeCurrentPage)
menuItems.Add(CreateBreadCrumb(currentPageData, currentPage, contentLoader, filter));
var pages = new List<PageData>();
do
{
var page = contentLoader.Get<PageData>(parentLink);
pages.Add(page);
parentLink = page.ParentLink;
} while (!parentLink.Equals(ContentReference.RootPage));
menuItems.AddRange(
pages.FilterForDisplay(requirePageTemplate, requireVisibleInMenu)
.Select(page => CreateBreadCrumb(page, currentPage, contentLoader, filter)));
menuItems.Reverse();
return menuItems.List(itemTemplate);
}
private static MenuItemViewModel CreateBreadCrumb(
PageData page,
ContentReference currentContentLink,
IContentLoader contentLoader,
Func<IEnumerable<PageData>, IEnumerable<PageData>> filter)
{
var menuItem = new MenuItemViewModel(page)
{
Selected = page.ContentLink.CompareToIgnoreWorkID(currentContentLink),
HasChildren = new Lazy<bool>(() => filter(contentLoader.GetChildren<PageData>(page.ContentLink)).Any())
};
return menuItem;
}
private static Func<IEnumerable<PageData>, IEnumerable<PageData>> GetFilter(bool requireVisibleInMenu, bool requirePageTemplate)
{
return pages => pages.FilterForDisplay(requirePageTemplate, requireVisibleInMenu);
}
而且,在你看來,
@helper BreadCrumb(MenuItemViewModel breadCrumbItem)
{
<li>
@if (breadCrumbItem.Page.HasTemplate() && !breadCrumbItem.Page.ContentLink.CompareToIgnoreWorkID(Model.CurrentPage.ContentLink))
{
@Html.PageLink(breadCrumbItem.Page)
}
else
{
@breadCrumbItem.Page.Name
}
</li>
}
<nav>
<ul>
@Html.BreadCrumbs(Model.CurrentPage.ContentLink, BreadCrumb, requireVisibleInMenu: false, includeCurrentPage: false)
</ul>
</nav>
此站點版本8.0.0.0。 –