I'm stumped on this one and hope someone out there's done something similar.
I have an ASP.NET application that has a number of AJAX toolkit tabs. The number of tabs varies page to page, since they're dynamically generated based on settings in a config file.
That being said, some of the tabs are database-driven. The load time when a number of these tabs are on the page can be significant, so I want to implement lazy loading.
I'm following Matt Berseth's pattern, but it seems to break down when the number of tabs is dynamic (each tab needs its own method on the page).
If anyone has a suggestion on how to tackle this, it'd be much appreciated.
I've started working with a small app to get the lazy loading to work. This lazy loads the second tab (which is hard coded), but the third tab is what I'm struggling with (it's dynamically added).
Edited to add code: ASPX page
<script language="javascript" type="text/javascript">
function clientActiveTabChanged(sender, args) {
// see if the table elements for the grids exist yet
var isTab2Loaded = $get('<%= this.lbl2.ClientID %>');
// if the tab does not exist and it is the active tab,
// trigger the async-postback
if (!isTab2Loaded && sender.get_activeTabIndex() == 1) {
// load tab1
__doPostBack('btnTrigger', '');
}
// else if (!isTab2Loaded && sender.get_activeTabIndex() == 2)
// load tab2
// __doPostBack('btnEmployeesTrigger', '');
}
</script>
<asp:scriptmanager ID="Scriptmanager1" runat="server"></asp:scriptmanager>
<div>
<cc1:TabContainer ID="tc1" runat="server" OnClientActiveTabChanged="clientActiveTabChanged">
<cc1:TabPanel TabIndex="0" runat="server" HeaderText="Tab1" ID="Tab1">
<ContentTemplate>
<asp:UpdatePanel ID="up1" runat="server">
<ContentTemplate>
<asp:Label ID="lbl1" text="I am here" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</cc1:TabPanel>
<cc1:TabPanel runat="server" HeaderText="Tab2" ID="Tab2">
<ContentTemplate>
<asp:UpdatePanel ID="up2" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Label ID="lbl2" Text="Load when called" Visible="false" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnTrigger" />
</Triggers>
</asp:UpdatePanel>
</ContentTemplate>
</cc1:TabPanel>
</cc1:TabContainer>
</div>
<input ID="btnTrigger" style="display:none;" runat="server" type="button" onserverclick="btnTrigger_Click" />
<input id="btnTrigger2" style="display:none;" runat="server" type="button" onserverclick="btnTrigger2_Click" />
Codebehind:
protected void Page_Init(object sender, EventArgs e)
{
//TabPanel tp = new TabPanel();
//tp.Controls.Add(new LiteralControl("Load first"));
//tp.HeaderText = "Tab1";
//tc1.Tabs.Add(tp);
//tc1.ActiveTabIndex = 0;
//TabPanel tp2 = new TabPanel();
//UpdatePanel up1 = new UpdatePanel();
//up1.Controls.Add(new LiteralControl("Load me when called"));
////up1.Triggers.Add(new AsyncPostBackTrigger());
//AsyncPostBackTrigger trg = new AsyncPostBackTrigger();
//tp2.Controls.Add(up1);
//tp2.Controls.Add(new Lite开发者_如何学CralControl("Load when called"));
//tp2.HeaderText = "Tab2";
//tc1.Tabs.Add(tp2);
TabPanel tp3 = new TabPanel();
tp3.HeaderText = "Tab3";
UpdatePanel up3 = new UpdatePanel();
LiteralControl lc = new LiteralControl("Load me when needed");
lc.ID = "lit3";
lc.Visible = false;
up3.ContentTemplateContainer.Controls.Add(lc);
tp3.Controls.Add(up3);
tc1.Controls.Add(tp3);
}
protected void btnTrigger_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(2500);
this.lbl2.Visible = true;
}
Is the content of the Tabs also database-driven like a CMS?
You could use UserControls as Content and let all implement the same interface f.e. IDataBindable
with a function BindData
. On this way you can lazyload these UserControl independently of its content.
On ActiveTabChanged
you only have to call this function and thenUpdate
on the TabContainer's UpdatePanel.
The quick way to do this might be to not load any tabs (i.e. don't actually give them any content) besides the default until that tab is clicked (detected during OnActiveTabChanged
or OnClientActiveTabChanged
).
However, Tim's method allows the OnActiveTabChanged
method to be as simple as databinding the UserControl
relative to that tab - that's probably the best method, though it is more effort.
精彩评论