业务系统设计之三:系统主控设计(下)
关于业务系统设计之系统主控设计,前一篇文章里已经将整个流程走了一便,最终开发出来的案例运行效果如下图:
本文将深入到系统主控的开发实现上,层层分析系统主控的各部分。首先从创建选项标签开始,通过点击菜单项来创建或选择一个已存在的选项标签,RadMenu和RadTabstrip控件对客户端事件的支持很强大,我们可以通过他的客户端事件去创建一个选项标签、选中一个存在的标签和关闭标签等等。
*开发日期:2008-11-08 Beniao
*参数说明:
* sender:执行请求的当前对象
* eventArgs:当前对象的事件
*------------------------------------------------
*>>>>>直接使用硬参数,Url值为相对路径(不加任何前缀修饰)
*/
function OnClientClick(sender, eventArgs)
{
var value = eventArgs.Item.Value; //隐藏Url
var text = eventArgs.Item.Text; //显示文本
//设置容器高度
SetContentHeight();
//关闭菜单项
CloseItem(sender, eventArgs);
//是否为首节点
if(IsFirstTab(value))
{
//显示当前页签
DisplayCurrentTab(text);
return;
}
if(value != '#')
{
//存在则直接显示(即实现选中)
if(IsExsitTab(value))
{
DisplayCurrentTab(text);
eventArgs.Item.Blur();
}
else
{
//是否为动态创建的第一个Tab
//不存在,创建新的
CreateTabPage(value,text);
eventArgs.Item.Blur();
}
}
}
首先通过RadMenu控件的客户端事件参数获取到菜单项的文本和隐藏的URL值,因为系统主控一般有一个默认的首页,当在创建或选择的时候都需要判断下当前是否为默认的首页。
*程序功能:是否为首节点
*开发日期:2008-11-08 20:15
*参数说明:
* requestUrl:请求的Url
*/
function IsFirstTab(requestUrl)
{
var flag = false;
if(requestUrl == "")
return flag;
if(requestUrl.toLowerCase() =="First.aspx".toLowerCase())
{
flag = true;
}
return flag;
}
如果当前页不是首页,则需要判断当前所选的菜单项的隐藏URL值是不是为“#”,数据库中的设计为如果是"#"则代表是顶层菜单项,否则则创建新的选项标签。这里又需要注意,如果将要创建的选项已经存在则选中就OK,如果不存在则创建。
*程序功能:判断当前页签是否存在
*开发日期:2008-11-08 10:20
*参数说明:
* requestUrl:请求的Url
*/
function IsExsitTab(requestUrl)
{
var flag = false;
var tabStrip = <%=RadTabStripMain.ClientID %>;
var ofrms = divMain.childNodes;
var count = ofrms.length;
for (var i = 0; i < count; i++)
{
//if(i == 1) continue;
var frmID = ofrms[i].id;
var index = GetIndex(frmID);
var value = tabStrip.Tabs[index].Value;
if(value.toLowerCase() == requestUrl.toLowerCase())
{
flag = true;
break;
}
}
return flag;
}
/*
*程序功能:显示当前页签
*开发日期:2008-11-08 10:20
*参数说明:
* text:Tab上显示的文本内容
*/
function DisplayCurrentTab(text)
{
var tab = <%=RadTabStripMain.ClientID %>.FindTabByText(text);
if(tab)
{
tab.SelectParents();
}
}
按照上面的代码则实现了判断是否为默认页---当前项是否存在---显示已经存在的选项标签。那要创建新的该怎么实现呢?这里首先需要弄清楚一个规则,实现多选项标签是利用的RadTabstrip控件的标签功能,而其下是通过iframe嵌入的一个页面,这个页面通过动态创建iframe包含到主控台上。其中每一个iframe的命名为:frm+一个数字(从0开始),如果要创建新的iframe则首先将现在的最大“frm数字”中的数字取出来然后加1,来作为新的选项标签的iframe的ID。
*程序功能:创建一个新的页签
*开发日期:2008-11-08 10:45
*参数说明:
* value:请求的Url
* text:显示的文本
*/
function CreateTabPage(requestUrl,text)
{
var tabStrip = <%=RadTabStripMain.ClientID %>;
var number = GetMaxNumber(tabStrip);
//动态创建选项卡
var li = document.createElement("li");
li.id='tab' + number;
var a = document.createElement('a');
a.id = 'Id' + number;
li.appendChild(a);
var span = document.createElement('span');
span.className = "wrap";
a.appendChild(span);
var span1 = document.createElement('span');
span1.className = "innerWrap";
var image = document.createElement('img');
image.src="Images/close.gif";
image.attachEvent("onclick",OnCloseTab);
image.attachEvent("onmouseover",function(){HightLight(image);}); //鼠标移入
image.attachEvent("onmouseout",function(){Normal(image);}); //鼠标移出
image.alt="关闭";
span1.appendChild(image);
span1.appendChild(document.createTextNode(text));
a.firstChild.appendChild(span1);
tabStrip.ChildStripDomElement.appendChild(li);
var tabObject = tabStrip.CreateTabObject(tabStrip,li.firstChild,number);
tabObject.Value = requestUrl; //Modify by Beniao at 2008-11-07 14:10
tabObject.Text = text;
tabObject.Initialize();
//为当前页签选项创建一个iframe并添加到界面上
CreateDivAppend(requestUrl,number);
//选中当前页签选项
var sid = "Id" + number;
var stab = tabStrip.FindTabById(sid);
stab.Select();
SetIndex(tabStrip, number);
SetImage(tabStrip, tabObject);
}
通过JavaScript动态的创建一个RadTabstrip控件的页签选项,然后又动态的创建一个DIV和iframe并将指定的页面包含到iframe中。
*程序功能:查找DIV对象(divMain),并根据参数新创建一个iframe对象追加到divMain的子节点上
*开发日期:2008-11-07 09:32
*参数说明:
* requestUrl:请求Url
* index:索引号
*/
function CreateDivAppend(requestUrl,index)
{
var divObject = document.getElementById("divMain");
//根据Url创建iframe
var oForm = CreateForm(requestUrl,index);
//将新创建的iframe追加到divMain的子节点中
divObject.appendChild(oForm);
}
/*
*程序功能:创建一个特定请求Url的iframe对象
*开发日期:2008-11-08 11:05
*参数说明:
* requestUrl:请求Url
* index:索引号
*/
function CreateForm(requestUrl,index)
{
var oFrom = document.getElementById("frm0");
var oFromNew = document.createElement("iframe");
oFromNew.id = "frm" + index; //新创建的iframe的唯一id
oFromNew.src = requestUrl;
oFromNew.style.position = "absolute";
oFromNew.style.setAttribute("left","0px");
oFromNew.style.setAttribute("top","0px");
oFromNew.style.setAttribute("width","100%");
oFromNew.style.setAttribute("height","100%");
oFromNew.style.setAttribute("z-index",index);
oFromNew.setAttribute("frameBorder","0");
oFromNew.setAttribute("marginHeight","0");
oFromNew.className="tabFrm";
return oFromNew;
}
创建和选择已存在的页签选项都已经完成,这一切都是通过菜单驱动完成的。用户自己选择已存在的其中一页签选项怎么实现的呢?这个功能很简单实现,RadTabstrip控件有这样的一个客户端API,只要实现这样一个方法就可以完成功能。
*程序功能:页签的选择事件
*开发日期:2008-11-08 11:30
*参数说明:无参数
*修改时间:2008-11-08 17:20
*/
function OnTabSelected()
{
//debugger;
var tabStrip = <%=RadTabStripMain.ClientID %>;
//当前所选择的页签
var selectTab = tabStrip.SelectedTab;
//如:Default.aspx
var requestUrl = selectTab.Value;
var oForms = divMain.childNodes;
var count = oForms.length;
//将第二个选项的关闭X图片处理掉
for ( var i = 0; i< count; i++)
{
//.
}
for (var i = 0; i < count; i++)
{
//当前选择的Tab相对应的iframe的id
var formID = oForms[i].id;
var index = GetIndex(formID);
if(document.getElementById(formID) != undefined)
{
if(document.getElementById(formID).getAttribute('src') != requestUrl)
{
document.getElementById(formID).style.display='none';
}
else
{
document.getElementById(formID).style.display='';
}
}
}
SetIndex(tabStrip, index);
SetImage(tabStrip, selectTab);
}
当我么双击页签选项的时候可实现关闭页签,这一功能也可以通过控件提供的客户端API来实现,实现API功能的方法就OK。
*程序功能:鼠标双击关闭当前页签
* 首页是不允许关闭的
*开发日期:2008-11-08 16:30
*参数说明:无参数
*/
function OnDoubleClick()
{
if(!IsDoubleClickClose())
{
RemoveTab();
}
}
/*
*程序功能:鼠标双击是否允许关闭当前页签(默认为不可关闭)
* 首页是不允许关闭的
*开发日期:2008-11-08 16:35
*参数说明:无参数
*/
function IsDoubleClickClose()
{
var flag = false;
var selectedTab = <%=RadTabStripMain.ClientID %>.SelectedTab;
var value = selectedTab.Value;
if(value == 'Default.aspx')
{
flag = true;
}
return flag;
}
其他的就是设置一些效果的功能开发了,这全是一些脚本的开发,主要就是利用RadMenu和RadTabstrip控件的客户端API来实现各种功能,详细也没有什么好介绍的,本文几乎全是代码短,不过我相信对大家有所帮助。
文中只是贴出了比较关键的代码以作参考,如果有什么不明白之处,请大家下载源代码了解。