如果你开发过DNN模块,你应该知道DNN每个模块都存在一个模块设置,在此你可以设置某一模块实例的相关信息,比如:模块名称,模块权限,模块容器皮肤等等。而有时你如果想扩展模块设置,增加自己的设置项,那你可以继承ModuleSettingsBase,该基类主要存在两个方法LoadSettings和UpdateSettings:
-
-
-
- Public Overrides Sub LoadSettings()
-
- End Sub
-
-
-
-
- Public Overrides Sub UpdateSettings()
- Try
- Dim objModules As New DotNetNuke.Entities.Modules.ModuleController
-
-
-
-
- Catch exc As Exception
- ProcessModuleLoadException(Me, exc)
- End Try
- End Sub
我想这对于DNN模块开发是比较方便,可是我偏偏对此极为抵触,觉得有时也许仅仅只有1-3个设置项,可每次都得跳转到模块设置页面里边,更新完毕又跳转回来,又得重新加载页面所有东西,值得么?不就更新几个值么?如此煞费心思,对比IGoogle的模块(不知你是否见识过,不妨先看看
http://www.google.com/ig?hl=en&source=iglk),都是Ajax方式更新,根本不需要每次都到后台设置。静下来琢磨一下,其实在DNN似乎也可以做到,只要借助一下UpdatePanel,而DNN核心API已对UpdatePanel封装起来,只要合理利用即可,该封装类为DotNetNuke.Framework.AJAX,下边不妨看看如何在DNN实现类IGoogle模块的效果:
1)在Page_Init事件里封装UpdatePanel,pnlLatest为目标容器,该容器里的即为你需要Ajax更新的数据列表等。
- Private Sub WrapUpdatePanel()
-
- AJAX.RegisterScriptManager()
- AJAX.WrapUpdatePanelControl(pnlLatest, False)
-
- End Sub
2)页面脚本处理,其中需要注意的是onInvoke和onComplete这两个函数,onInvoke负责提交数据到服务器,而onComplete将在数据返回客户端,完成更新后激发。
- <script language="javascript" type="text/javascript">
- var Module_Container;
- function initContainerID(){
- if ( typeof(Module_Container) === 'undefined') Module_Container = dnn.getVar('Container_ID');
- }
-
- Sys.Net.WebRequestManager.add_invokingRequest(onInvoke);
- Sys.Net.WebRequestManager.add_completedRequest(onComplete);
-
- function onInvoke(sender, args){
- initContainerID();
- $get(Module_Container + "lstContent").style.display = 'none';
- $get("updateProgress").style.display = '';
- }
-
- function onComplete(sender, args){
- initContainerID();
- $get(Module_Container + "lstContent").style.display = 'none';
- $get("updateProgress").style.display = 'none';
- }
- </script>
- <asp:Panel ID="pnlLatest" runat="server">
- <!-- 你需要Ajax更新的数据列表 ,其中包括一个Datalist控件(id为lstContent)(已省略)-->
- </asp:Panel>
- <div id="updateProgress" style="display:none;">
- On updating the entries list, plaese waiting for ...
- </div>
3)更新模块设置:
- Private Sub btnUpdate_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnUpdate.Click
- RecentEntriesMax = Convert.ToInt32(ddlEntriesMax.SelectedValue)
- Dim objModules As New ModuleController
- objModules.UpdateModuleSetting(ModuleId, "LatestEntriesMax", RecentEntriesMax)
- objModules.UpdateModuleSetting(ModuleId, "ContentLength", txtLengthMax.Text)
-
-
- BindEntriesList()
- End Sub
解析:从这可看出,最终还得需要UpdateModuleSetting来实现我们的功能,只不过是借助了Ajax来更新吧。也就是当点击按钮btnUpdate提交数据时将会触发onInvoke脚本实现了Ajax方式的更新(原因就是更新操作已被封装在UpdatePanel),在此我们没有详细讲述Sys.Net.WebRequestManager的原理机制:
- Sys.Net.WebRequestManager.add_invokingRequest(onInvoke);
- Sys.Net.WebRequestManager.add_completedRequest(onComplete);
如果有兴趣可以看看官方文档。
4)以上更新过程还得需要一辅助脚本dnn.js,故切记在Page_Load里添加该命名空间的注册:
- ClientAPI.RegisterClientVariable(Me.Page, "Container_ID", Me.ClientID + "_", True)
-
-
- ClientAPI.RegisterClientReference(Me.Page, ClientAPI.ClientNamespaceReferences.dnn)
进阶应用:
其实你还可以控制设置项何时出现,比如一般在编辑状态才出现,否则自动隐藏。这一功能可用不同方法实现,在此我还是发扬“物进所用”精神,借助DNN的Personalization机制来控制控制设置项的呈现。
- Dim Mode As String = CType(DotNetNuke.Services.Personalization.Personalization.GetProfile("Usability", "UserMode" & Me.PortalSettings.PortalId.ToString), String)
-
- If Mode = "Edit" Then
-
- tblSettings.Visible = True
- btnUpdate.Visible = True
- End If
关于Personalization服务,这是一个DNN极其有用的核心机制,也许以后文章会有所涉及,先不妨看看下边链接,相信你会有所收获: