Für Ihre Bedenken über PageData
:
PageData
Objekte (und alle Derivate Sie in Ihrem eigenen System ("ArticlePage", "ListPage" oder andere) erstellen, werden im Arbeitsspeicher zwischengespeichert Im Vergleich zu "FooBar-style" Tutorial. Beispiel Klassen, es ist enorm, aber im wirklichen Leben, können Sie leicht Hunderte von ihnen für eine einzelne Seite laden auf einem modernen Server. Fügen Sie einige Ausgabe-Caching oder andere Caching-Lösungen, und es wird ein Nicht-Problem in der Praxis Bündel von Get<T>(...)
und GetChildren<T>(...)
für jede Anfrage ist völlig in Ordnung.
Es ist wahr, dass es viele Eigenschaften hat , aber es ist wahrscheinlich besser, eine "Quelle der Wahrheit" für ein bestimmtes Seitenobjekt zu haben, als benutzerdefinierte Abfragen für jede einzelne Verwendung in Ihrer gesamten Site zu haben. Plötzlich wirst du eine Texteigenschaft haben wollen, die du definiert hast. Oder greifen Sie auf die Zugriffskontrollliste zu. Oder überprüfen Sie den Inhaltstyp. Oder editiere es und speichere es.
Zum Beispiel: In einem einfachen Menü, werden Sie beide wahrscheinlich seinen Namen wollen, möglicherweise eine Form von „Intro“, „Auszug“ oder „MainIntro“ Eigenschaft ist es ContentLink
(der Istwert für <a href=...>
erstellen) Auch , behandeln Sie oft Elemente eines bestimmten Typs und nicht die Basisklasse PageData
, die zu noch mehr Eigenschaften führt, die Sie selbst definieren.
So keine, ist es nicht unnötig noch zu viel Aufwand. Es ist üblich, und es funktioniert. Wenn Sie während der Bearbeitung nicht alle Eigenschaften anzeigen möchten, können Sie sie einfach als IContent
behandeln. Beachten Sie jedoch, dass die dahinterstehende Implementierung immer noch PageData
Objekte (oder vielmehr Laufzeit-generierte Proxy-Klassen für den tatsächlichen Seitentyp, den Sie abrufen) ist.
Abgesehen davon:
- Sie sollten nicht in einer Ansicht wie viel Code setzen. Programmlogik gehört zu Controllern oder anderen Klassen. Dies hat nichts mit Episerver zu tun, sondern eher mit allgemeinen Best Practices.
- sollten Sie vermeiden
DataFactory
Zugriff und eher IContentLoader
über Dependency Injection (entweder als Konstruktorparameter abrufen oder über ServiceLocator.Current.GetInstance<IContentLoader>
Hier ist eine flexible und einfache Möglichkeit, Paniermehl zu tun.
Erstellen Sie eine Datei wie HtmlHelperExtensions.cs
, welche enthält:
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);
}
Und aus Ihrer Sicht;
@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>
Diese Website hat die Version 8.0.0.0. –