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

相關文章
相關標籤/搜索