标签:
CatalogController 方法public ActionResult TopMenu()
//categories var customerRolesIds = _workContext.CurrentCustomer.CustomerRoles .Where(cr => cr.Active).Select(cr => cr.Id).ToList(); string categoryCacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_MENU_MODEL_KEY, _workContext.WorkingLanguage.Id, string.Join(",", customerRolesIds), _storeContext.CurrentStore.Id); var cachedCategoriesModel = _cacheManager.Get(categoryCacheKey, () => PrepareCategorySimpleModels(0, null, 0, _catalogSettings.TopCategoryMenuSubcategoryLevelsToDisplay, true) .ToList() );
第一句 返回所有角色的ID。
第二句 创建一个分类缓存KEY。
第三句 根据这个KEY作为缓存KEY,用如下方法获得所有menu集合。
/// <summary> /// Prepare category (simple) models /// </summary> /// <param name="rootCategoryId">Root category identifier 根类识别符--0</param> /// <param name="loadSubCategoriesForIds">Load subcategories only for the specified category IDs; pass null to load subcategories for all categories</param>
/// 为指定类别加载子类别,NULL用于加载所有类别的子类别—NULL /// <param name="level">Current level 当前级别--0</param> /// <param name="levelsToLoad">A value indicating how many levels to load (max) 一个值指示有多少级别用于加载--_catalogSettings.TopCategoryMenuSubcategoryLevelsToDisplay</param> /// <param name="validateIncludeInTopMenu">A value indicating whether we should validate "include in top menu" property一个值用于确认“包含在顶菜单”属性</param> /// <returns>Category models 返回类别实体集合</returns> [NonAction] protected virtual IList<CategorySimpleModel> PrepareCategorySimpleModels(int rootCategoryId, IList<int> loadSubCategoriesForIds, int level, int levelsToLoad, bool validateIncludeInTopMenu) { var result = new List<CategorySimpleModel>(); new一个CategorySimpleModel集合 foreach (var category in _categoryService.GetAllCategoriesByParentCategoryId(rootCategoryId)) { 根据根类识别符(0)循环获得的所有父类类别 if (validateIncludeInTopMenu && !category.IncludeInTopMenu) {如果验证 并且 类别的IncludeInTopMenu属性为false,也就是不包含在顶部菜单 则不往下操作,继续循环。 continue; } var categoryModel = new CategorySimpleModel {new一个CategorySimpleModel对象 Id = category.Id, Name = category.GetLocalized(x => x.Name), SeName = category.GetSeName() }; //product number for each category每个类别的产品数量 if (_catalogSettings.ShowCategoryProductNumber) {如果设置显示类别产品数量 var customerRolesIds = _workContext.CurrentCustomer.CustomerRoles .Where(cr => cr.Active).Select(cr => cr.Id).ToList(); string cacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_NUMBER_OF_PRODUCTS_MODEL_KEY, string.Join(",", customerRolesIds), _storeContext.CurrentStore.Id, category.Id); categoryModel.NumberOfProducts = _cacheManager.Get(cacheKey, () => { var categoryIds = new List<int>(); categoryIds.Add(category.Id); //include subcategories if (_catalogSettings.ShowCategoryProductNumberIncludingSubcategories) categoryIds.AddRange(GetChildCategoryIds(category.Id)); return _productService.GetCategoryProductNumber(categoryIds, _storeContext.CurrentStore.Id); }); } //load subcategories? bool loadSubCategories = false; if (loadSubCategoriesForIds == null) { //load all subcategories加载所有子类别 loadSubCategories = true; } else { //we load subcategories only for certain categories只为某些类别加载子类别 for (int i = 0; i <= loadSubCategoriesForIds.Count - 1; i++) { if (loadSubCategoriesForIds[i] == category.Id) { loadSubCategories = true; break; } } } if (levelsToLoad <= level) {如果当前级别大于等于要加载的级别(3》2 其实是更小一级的级别),设置加载子类别为false. loadSubCategories = false; } if (loadSubCategories) {递归调用本方法返回子类列表 添加到categoryModel.SubCategories var subCategories = PrepareCategorySimpleModels(category.Id, loadSubCategoriesForIds, level + 1, levelsToLoad, validateIncludeInTopMenu); categoryModel.SubCategories.AddRange(subCategories); }
添加到列表 result.Add(categoryModel); } 返回 return result; }
返回主方法:
//top menu topics顶部菜单话题(论题) string topicCacheKey = string.Format(ModelCacheEventConsumer.TOPIC_TOP_MENU_MODEL_KEY, _workContext.WorkingLanguage.Id, _storeContext.CurrentStore.Id);缓存KEY var cachedTopicModel = _cacheManager.Get(topicCacheKey, () => _topicService.GetAllTopics(_storeContext.CurrentStore.Id)返回所有IncludeInTopMenu为true的TopMenuModel .Where(t => t.IncludeInTopMenu) .Select(t => new TopMenuModel.TopMenuTopicModel { Id = t.Id, Name = t.GetLocalized(x => x.Title), SeName = t.GetSeName() }) .ToList() );
最后:返回一个对象。
var model = new TopMenuModel { Categories = cachedCategoriesModel, Topics = cachedTopicModel, RecentlyAddedProductsEnabled = _catalogSettings.RecentlyAddedProductsEnabled,启用最近添加的产品? BlogEnabled = _blogSettings.Enabled,博客是否可用 ForumEnabled = _forumSettings.ForumsEnabled论坛 }; return PartialView(model);
最后看页面:
@model CategoryNavigationModel @using Nop.Web.Models.Catalog; @functions{ public bool BreadCrumbContainsCurrentCategoryId(CategorySimpleModel category) { if (Model.CurrentCategoryId == 0) return false; if (category.Id == Model.CurrentCategoryId) return true; foreach (var subCategory in category.SubCategories) { if (BreadCrumbContainsCurrentCategoryId(subCategory)) { return true; } } return false; } } @helper RenderCategoryLine(CategorySimpleModel category) { <li class="@(category.Id == Model.CurrentCategoryId ? "active" : "inactive")"> <a href="@Url.RouteUrl("Category", new { SeName = category.SeName })">@category.Name @if (category.NumberOfProducts.HasValue) { <text> </text>@T("Categories.TotalProducts", category.NumberOfProducts.Value) } </a> @{ if (category.Id == Model.CurrentCategoryId || category.SubCategories.Count(BreadCrumbContainsCurrentCategoryId) > 0) { if (category.SubCategories.Count > 0) { <ul class="sublist"> @foreach (var subCategory in category.SubCategories) { @RenderCategoryLine(subCategory) } </ul> } } } </li> } @if (Model.Categories.Count > 0) { <div class="block block-category-navigation"> <div class="title"> <strong>@T("Categories")</strong> </div> <div class="listbox"> <ul class="list"> @foreach (var category in Model.Categories) { @RenderCategoryLine(category) } </ul> </div> </div> }
functions 和helper 个人理解 前者就是C#方法 后者可以包含HTML标签 不过前者也可以返回HtmlString 使用var listItem = new TagBuilder("li");等详见:
http://www.cnblogs.com/jiagoushi/p/3904995.html
标签:
原文地址:http://www.cnblogs.com/runit/p/4432618.html