与母版页间的通信
在网站开发的过程中,经常会遇到“页面复用”的情况。所以聪明的人们想了很多方法:
第一、将复用的页面脚本存于txt文件中。
第二、将复用页面构造成字符串。
第三、frame、frameset、iframe等。
第四、微软提供了模板页(此处指讨论.NET方面的开发)。
(目前用到的就这几种咯。。。)
相比之下,第一种、第三种、第三种方案会多一次IO操作(frame等有时甚至会多很多次),性能相对较慢。所以从性能上而言。将复用页面构造成字符串是最好的。但是随着复用页面的复杂度的替身,构造的字符串会相当的复杂,维护非常麻烦。
当网站对性能没有特别要求时,我们来分析下第一、第三、第四种方案。
首先,我们会放弃第一种方案,因为读取出来的页面内容肯定是放在String字符串中,如果字符串中有负数字符等,必定少不了对字符串的处理等工作。维护的工作量没有减少,相对而言有所增加。
其次,比较下第三、第四种方案。如果不考虑性能,第三和第四种方案几乎没有任何区别。但是,第三种方案:当页面加载时,页面会同时加载frame中的复用页面,有同仁说这正好降低了服务器的负担。然后相反,这正好增加了服务器的负担,原因如后在述。第四种方案:当页面加载时,系统会根据页面中的<%@ Page MasterPageFile="~/test/masterPageTest/MasterPage.master" %>需找母版,然后首先加载母版页,再加载子页。所以性能方面的负担就出来了。当一个人同时给你两拳,和一个人先给你一拳再给你一拳。哪种你更能承受,可想而知。
然而,讲究共享数据而言,第二种方案具有一定优势。
加载当前页面时候,我们经常会做一些数据库查询、绑定等的类似操作,如何做到复用页共享当前页的数据,是个麻烦事。当然你也可以选择在不同的页面分别查询,如果你的系统对性能没有要求的话。
第一种方案,如果修改文本文件中的数据,相当麻烦,相信很多人都不会使用,除非是xml或txt中保存序列化后的对象(这种情况在复用页面中基本不存在)我还愿意考虑下。
第二种方案,函数处理。传入参数,返回绑定结果。
第三种方案,加载时绑定frame中的数据,几乎不可能。
第四种方案,加载时母版页共享当前页数据,几乎不可能。
所以第一、第三、第四种方案只有是加载完成时在进行数据绑定。其实有人会问第三种方案也是先加载然后在绑定的啊。说起来确实是,但是第二种方案的绑定之伴随着HTml一起产生的。第一、第三、第四种方案是先产生HTML,再产生绑定结果,如果绑定数量过大,复杂度可想而知,而且这样的代码恐怕更难维护,因为绑定是分散在各个页面中的。
好了。说了这么多废话,还没进入正题。说说ASP.NET中如何与母版页通信吧。当然,如果你还有更好的构造方式,可以提出来,坚决欢迎这样的意见。
都知道在当前页是通过<%@ Page MasterPageFile="~/test/masterPageTest/MasterPage.master" %>来访问母版页的。如果你要访问母版页面中的成员,只需在其后加一句<%@ MasterType VirtualPath="母版页地址" %>即可,作用为:用@MasterType指令来创建对母版页的强类型引用。
代码如下:
<%@ Page Title="" Language="C#" MasterPageFile="~/test/masterPageTest/MasterPage.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="test_masterPageTest_Default" %>
<%@ MasterType VirtualPath="~/test/masterPageTest/MasterPage.master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<asp:Button ID="showButton" runat="server" Text="知道了"
onclick="showButton_Click" />
<asp:Button ID="hideButton" runat="server" Text="去死吧"
onclick="hideButton_Click" />
</asp:Content>
添加了强类型以后之后,我们就可以访问母版页中的成员了,因此我写了如下代码:
protected void showButton_Click(object sender, EventArgs e)
{
//this.Master.mpLabel.Visible = true;
this.Master.MasterPageLabel.Visible = true;
}
protected void hideButton_Click(object sender, EventArgs e)
{
this.Master.MasterPageLabel.Visible = false;
}
但是令我意外的报错了,无法访问,因为MasterPageLabel是受保护的。说到这里还没有说明MasterPageLabel是什么东东呢。粘贴一下母版页的代码:
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="test_masterPageTest_MasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="MasterPageLabel" runat="server" Text="我是母版,我是母版。。。"></asp:Label>
<br />
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
MasterPageLabel就是母版页中的一个Label。因此走到这里,会得出一个结论,母版页中的控件是受保护的无法直接访问。。。。糟了,既然控件无法访问,我们如何绑定呢?错误提示他是后保护的,好,我们就让他不受保护吧。温室里面长大的孩子不好,太脆弱,因此:
public Label mpLabel
{
get
{
return MasterPageLabel;
}
set
{
MasterPageLabel = value;
}
}
我把MasterPageLabel的访问封装成了属性,同时,改下当前页的代码:
protected void showButton_Click(object sender, EventArgs e)
{
//this.Master.mpLabel.Visible = true;
this.Master.mpLabel.Visible = true;
}
protected void hideButton_Click(object sender, EventArgs e)
{
this.Master.mpLabel.Visible = false;
}