MVC架构,首先”急功近利“选择V下手,在路由中可以看到路由配置中的View,找到首页View
Nop.Web\Views\Home\Index.cshtml
- @{
- Layout = "~/Views/Shared/_ColumnsThree.cshtml";
- }
- <div class="page home-page">
- <div class="page-body">
- @Html.Widget("home_page_top")
- @Html.Action("TopicBlock", "Topic", new { systemName = "HomePageText" })
- @Html.Action("HomepageCategories", "Catalog")
- @Html.Action("HomepageProducts", "Product")
- @Html.Action("HomepageBestSellers", "Product")
- @Html.Action("HomePageNews", "News")
- @Html.Action("HomePagePolls", "Poll")
- @Html.Widget("home_page_bottom")
- </div>
- </div>
页面分布局及内容分块,在asp.net MVC中常用的方法是share文件夹中的布局视图
- Layout = "~/Views/Shared/_ColumnsThree.cshtml";
分块中常采取的办法有Partial视图或是Action,如上的Html.Action("HomepageCategories", "Catalog")
NopCommerce中还实现了Widget部件的方法
它其实是采用HtmlHelper的扩展方法:
public static mvcHtmlString Widget(this HtmlHelper helper, string widgetZone, object additionalData = null)
- {
- return helper.Action("WidgetsByZone", "Widget", new { widgetZone = widgetZone, additionalData = additionalData });
- }
Widget部件实质又使用Action实现
扩展方法调用的是WidgetController中的WidgetByZone方法,最终返回的一个类型为MvcHtmlString字符串。
WidgetsByZone方法:
- [ChildActionOnly]
- public ActionResult WidgetsByZone(string widgetZone, object additionalData = null)
- {
- var cacheKey = string.Format(ModelCacheEventConsumer.WIDGET_MODEL_KEY, _storeContext.CurrentStore.Id, widgetZone);
- var cacheModel = _cacheManager.Get(cacheKey, () =>
- {
- //获取部件的Model集合
- var model = new List<RenderWidgetModel>();
- var widgets = _widgetService.LoadActiveWidgetsByWidgetZone(widgetZone, _storeContext.CurrentStore.Id);
- foreach (var widget in widgets)
- {
- var widgetModel = new RenderWidgetModel();
- string actionName;
- string controllerName;
- RouteValueDictionary routeValues;
- widget.GetDisplayWidgetRoute(widgetZone, out actionName, out controllerName, out routeValues);
- widgetModel.ActionName = actionName;
- widgetModel.ControllerName = controllerName;
- widgetModel.RouteValues = routeValues;
- model.Add(widgetModel);
- }
- return model;
- });
- //no data?
- if (cacheModel.Count == 0)
- return Content("");
- //"RouteValues" property of widget models depends on "additionalData".
- //We need to clone the cached model before modifications (the updated one should not be cached)
- var clonedModel = new List<RenderWidgetModel>();
- foreach (var widgetModel in cacheModel)
- {
- var clonedWidgetModel = new RenderWidgetModel();
- clonedWidgetModel.ActionName = widgetModel.ActionName;
- clonedWidgetModel.ControllerName = widgetModel.ControllerName;
- if (widgetModel.RouteValues != null)
- clonedWidgetModel.RouteValues = new RouteValueDictionary(widgetModel.RouteValues);
- if (additionalData != null)
- {
- if (clonedWidgetModel.RouteValues == null)
- clonedWidgetModel.RouteValues = new RouteValueDictionary();
- clonedWidgetModel.RouteValues.Add("additionalData", additionalData);
- }
- clonedModel.Add(clonedWidgetModel);
- }
- return PartialView(clonedModel);
- }
这个Action对应的视图Nop.Web\Views\Widget\WidgetsByZone.cshtml
@model List<RenderWidgetModel>
- @using Nop.Web.Models.Cms;
- @foreach (var widget in Model)
- {
- @Html.Action(widget.ActionName, widget.ControllerName, widget.RouteValues)
- }
可以看出,部件可以再包含部件或部件列
部件本身也是MVC模式,其M的实现为WidgetService
在WidgetController中的Action方法WidgetsByZone中我们可以看到里面最终调用WidgetService的方法LoadActiveWidgetsByWidgetZone并把结果缓存起来,而LoadActiveWidgetsByWidgetZone返回是一个类型IWidgetPlugin部件插件集合IList<IWidgetPlugin>。
public virtual IList<IWidgetPlugin> LoadActiveWidgetsByWidgetZone(string widgetZone, int storeId = 0)
- {
- if (String.IsNullOrWhiteSpace(widgetZone))
- return new List<IWidgetPlugin>();
- return LoadActiveWidgets(storeId)
- .Where(x => x.GetWidgetZones().Contains(widgetZone, StringComparer.InvariantCultureIgnoreCase))
- .ToList();
- }
- public virtual IList<IWidgetPlugin> LoadAllWidgets(int storeId = 0)
- {
- return _pluginFinder.GetPlugins<IWidgetPlugin>(storeId: storeId).ToList();
标签:展示,widgetModel,var,Html,widgetZone,NopCommerce,Action,new,页面 From: https://www.cnblogs.com/5x19/p/16917114.html