nopcommerce的挂件技术之二

上一篇新建了一个插件的demo(http://www.cnblogs.com/SecondSun/p/7422036.html),里面还有些问题没讲清楚,这篇,我将详细的讲解下。html

关于 “ @Html.Widget("home_page_helloworld")”这个问题,这里面的参数须要和plugin中GetWidgetZones返回参数一致,不然没法加载插件。这个“home_page_helloworld”至关于一个ID,区分不一样的插件,下面,咱们来了解下是如何实现的。缓存

首先@Html.Widget是HtmlHelper方法的扩展,代码以下:this

  public static MvcHtmlString Widget(this HtmlHelper helper, string widgetZone, object additionalData = null, string area = null)
        {
            return helper.Action("WidgetsByZone", "Widget", new { widgetZone = widgetZone, additionalData = additionalData, area = area });
            //return helper.Action("WidgetsByZone", "Home", new { widgetZone = widgetZone, additionalData = additionalData, area = area });
        }

能够看到,该方法主要是调用“WidgetController”中的“WidgetsByZone”方法,真正的处理逻辑也是在这里的。具体的实现:spa

 1  [ChildActionOnly]
 2         public ActionResult WidgetsByZone(string widgetZone, object additionalData = null)
 3         {
 4             var cacheKey = string.Format(ModelCacheEventConsumer.WIDGET_MODEL_KEY, widgetZone);
 5             var cacheModel = _cacheManager.Get(cacheKey, () =>
 6             {
 7                 //model
 8                 var model = new List<RenderWidgetModel>();
 9 
10                 var widgets = _widgetService.LoadActiveWidgetsByWidgetZone(widgetZone);
11                 foreach (var widget in widgets)
12                 {
13                     var widgetModel = new RenderWidgetModel();
14 
15                     string actionName;
16                     string controllerName;
17                     RouteValueDictionary routeValues;
18                     widget.GetDisplayWidgetRoute(widgetZone, out actionName, out controllerName, out routeValues);
19                     widgetModel.ActionName = actionName;
20                     widgetModel.ControllerName = controllerName;
21                     widgetModel.RouteValues = routeValues;
22 
23                     model.Add(widgetModel);
24                 }
25                 return model;
26             });
27 
28             //若是没有Model返回为空字符串
29             if (!cacheModel.Any())
30                 return Content("");
34             var clonedModel = new List<RenderWidgetModel>();
35             foreach (var widgetModel in cacheModel)
36             {
37                 var clonedWidgetModel = new RenderWidgetModel();
38                 clonedWidgetModel.ActionName = widgetModel.ActionName;
39                 clonedWidgetModel.ControllerName = widgetModel.ControllerName;
40                 if (widgetModel.RouteValues != null)
41                     clonedWidgetModel.RouteValues = new RouteValueDictionary(widgetModel.RouteValues);
42 
43                 if (additionalData != null)
44                 {
45                     if (clonedWidgetModel.RouteValues == null)
46                         clonedWidgetModel.RouteValues = new RouteValueDictionary();
47                     clonedWidgetModel.RouteValues.Add("additionalData", additionalData);
48                 }
49 
50                 clonedModel.Add(clonedWidgetModel);
51             }
52 
53             return PartialView(clonedModel);
54         }

首先,根据键值对从缓存中读取数据,若是缓存中没有,则根据名称查找活动的组件LoadActiveWidgetsByWidgetZone(widgetZone)。查找返回实体。最后,咱们须要在修改以前克隆缓存的模型(更新的模型不该被缓存),返回克隆的模型。插件

WidgetsByZone的视图以下所示:code

@model List<RenderWidgetModel>
@using NopFramework.Web.Models.Cms;
@foreach (var widget in Model)
{
    @Html.Action(widget.ActionName, widget.ControllerName, widget.RouteValues)
}

遍历Model中的数据,并执行widget中指定Controller中的Action。该例子中的action、controller分别对应PublicInfo和WidgetsHelloWorld即直接加载插件,执行publicInfo方法,这样插件就显示出来了。orm

相关文章
相关标签/搜索