Register  |   Login
关于本人
Baldwin's Status
Ramblings of a developer for dnn solution...
 Contact Me
随笔档案
Blog搜索
相册库
更多照片请查看相册库
最新评论
Rss Feed
feedsky
抓虾
pageflakes
newsgator
哪吒
我们的服务
  • DotNetNuke 咨询
  • Web设计及其模块开发
  • 免费建站
  • 电子商务
  • 开拓市场
我们致力于开发定制的web 2.0 ,所服务的客户主要包括小中型企业,社区俱乐部及其非盈利机构组织。我们将利用开源的DNN作为我们核心的系统机制,更多相关信息...

如何在DNN创建类IGoogle效果的模块

Posted in [DNN核心代码], [DNN模块开发], [优化DNN] By baldwin

如果你开发过DNN模块,你应该知道DNN每个模块都存在一个模块设置,在此你可以设置某一模块实例的相关信息,比如:模块名称,模块权限,模块容器皮肤等等。而有时你如果想扩展模块设置,增加自己的设置项,那你可以继承ModuleSettingsBase,该基类主要存在两个方法LoadSettings和UpdateSettings:
 
  1. ''' <summary>   
  2. ''' LoadSettings loads the settings from the Database and displays them   
  3. ''' </summary>   
  4. Public Overrides Sub LoadSettings()   
  5.     ' get the module setting   
  6. End Sub  
  7.   
  8. ''' <summary>   
  9. ''' UpdateSettings saves the modified settings to the Database   
  10. ''' </summary>   
  11. Public Overrides Sub UpdateSettings()   
  12.     Try  
  13.         Dim objModules As New DotNetNuke.Entities.Modules.ModuleController   
  14.            
  15.         'Update Module Settings   
  16.         'objModules.UpdateModuleSetting(ModuleId, "surveyclosingdate", DotNetNuke.Common.Globals.DateToString(datClosingDate))   
  17.   
  18.     Catch exc As Exception    'Module failed to load   
  19.         ProcessModuleLoadException(Me, exc)   
  20.     End Try  
  21. End Sub  
更多相关的信息请参看我之前的文章“DNN模块开发之利器篇:七种武器
我想这对于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更新的数据列表等。
 
  1. Private Sub WrapUpdatePanel()   
  2.     'If AJAX.IsInstalled Then   
  3.     AJAX.RegisterScriptManager()   
  4.     AJAX.WrapUpdatePanelControl(pnlLatest, False)   
  5.     'End If   
  6. End Sub  
2)页面脚本处理,其中需要注意的是onInvoke和onComplete这两个函数,onInvoke负责提交数据到服务器,而onComplete将在数据返回客户端,完成更新后激发。
 
  1. <script language="javascript" type="text/javascript">   
  2. var Module_Container;   
  3. function initContainerID(){   
  4.     if ( typeof(Module_Container) === 'undefined')   Module_Container = dnn.getVar('Container_ID');   
  5. }   
  6.   
  7. Sys.Net.WebRequestManager.add_invokingRequest(onInvoke);   
  8. Sys.Net.WebRequestManager.add_completedRequest(onComplete);   
  9.   
  10. function onInvoke(sender, args){   
  11.     initContainerID();   
  12.     $get(Module_Container + "lstContent").style.display = 'none';   
  13.     $get("updateProgress").style.display = '';   
  14. }   
  15.   
  16. function onComplete(sender, args){   
  17.     initContainerID();   
  18.     $get(Module_Container + "lstContent").style.display = 'none';   
  19.     $get("updateProgress").style.display = 'none';   
  20. }   
  21. </script>   
  22. <asp:Panel ID="pnlLatest" runat="server">   
  23.     <!-- 你需要Ajax更新的数据列表 ,其中包括一个Datalist控件(id为lstContent)(已省略)-->   
  24. </asp:Panel>   
  25. <div id="updateProgress" style="display:none;">   
  26. On updating the entries list, plaese waiting for ...   
  27. </div>  
3)更新模块设置:
 
  1. Private Sub btnUpdate_Click(ByVal sender As ObjectByVal e As System.EventArgs) Handles btnUpdate.Click   
  2.     RecentEntriesMax = Convert.ToInt32(ddlEntriesMax.SelectedValue)   
  3.     Dim objModules As New ModuleController   
  4.     objModules.UpdateModuleSetting(ModuleId, "LatestEntriesMax", RecentEntriesMax)   
  5.     objModules.UpdateModuleSetting(ModuleId, "ContentLength", txtLengthMax.Text)   
  6.   
  7.     'ReBind the data list   
  8.     BindEntriesList()   
  9. End Sub  
解析:从这可看出,最终还得需要UpdateModuleSetting来实现我们的功能,只不过是借助了Ajax来更新吧。也就是当点击按钮btnUpdate提交数据时将会触发onInvoke脚本实现了Ajax方式的更新(原因就是更新操作已被封装在UpdatePanel),在此我们没有详细讲述Sys.Net.WebRequestManager的原理机制:
 
  1. Sys.Net.WebRequestManager.add_invokingRequest(onInvoke);   
  2. Sys.Net.WebRequestManager.add_completedRequest(onComplete);  
如果有兴趣可以看看官方文档。
4)以上更新过程还得需要一辅助脚本dnn.js,故切记在Page_Load里添加该命名空间的注册:
 
  1. ClientAPI.RegisterClientVariable(Me.Page, "Container_ID"Me.ClientID + "_"True)   
  2. 'Requires at a bare minimum the dnn namespace,    
  3. 'so we need to register it regardless of wheter the ClientAPI is disabled or not    
  4. ClientAPI.RegisterClientReference(Me.Page, ClientAPI.ClientNamespaceReferences.dnn)  
关于原因,还是看看刚才提到的文章“DNN模块开发之利器篇:七种武器
进阶应用:
其实你还可以控制设置项何时出现,比如一般在编辑状态才出现,否则自动隐藏。这一功能可用不同方法实现,在此我还是发扬“物进所用”精神,借助DNN的Personalization机制来控制控制设置项的呈现。
 
  1. Dim Mode As String = CType(DotNetNuke.Services.Personalization.Personalization.GetProfile("Usability""UserMode" & Me.PortalSettings.PortalId.ToString), String)   
  2. ' TODO ( due to the Hard-Code snippet)   
  3. If Mode = "Edit" Then  
  4.     'Show the setting controls   
  5.     tblSettings.Visible = True  
  6.     btnUpdate.Visible = True  
  7. End If  
关于Personalization服务,这是一个DNN极其有用的核心机制,也许以后文章会有所涉及,先不妨看看下边链接,相信你会有所收获:
模块演示(Demo版本): IGoogle版本的Blog扩展演示
This posting is provided "AS IS" with no warranties, and confers no rights.

Previous Entry:不一样的分页算法
Next Entry:创业的箴言摘录

Comments

Was it good for you, too?Join the discussion » ,but you need to login first before you make comments.