我如何隐藏空嵌套的中继器



在ASP.NET页面中,我嵌套了中继器,可以显示我的站点地图的四个级别。

问题: 我如何告诉嵌套的中继器,如果没有孩子没有孩子,请不要显示一个节点?它呈现为一对<ul></ul>标签 - 这就是我需要从渲染列表中隐藏的。

有效的工作:此处介绍的HTML和脚本将Web.sitemap正确地呈现为一个干净的无序列表,只有带有节点没有孩子的空的UL标签。

到目前为止我尝试过的(不幸):

  • 我已经调查了jQuery。尽管我找到了正确的jQuery命令来删除空的<ul>对,但Webresource绝对确保覆盖jQuery命令。(这也使我无法使用jQuery删除插入ASP:菜单的乱码的类)。换句话说,我尚未找到一种清理ASP.NET控制产生的东西的方法。
  • 我找到了论坛帖子,但他们似乎都重复了相同的两级深度中继器而没有删除无子节点。
  • 我对我的web.sitemap文件进行了仔细检查,并确保我在来源中没有任何贡献。来源没有问题。

环顾四周,我在这里找到了一篇非常有前途的帖子:当孩子中继器空着时,将孩子和家长中继器隐藏起来。将其调整为vb.net并添加一个空检测,如果是然后,我有:

Protected Sub HideIfEmpty(sender As Object, e As RepeaterItemEventArgs) Handles Repeater0.ItemDataBound
    If e.Item.ItemType = ListItemType.Item Then
        If e.Item.FindControl("Repeater4") IsNot Nothing Then
            If (DirectCast(e.Item.FindControl("Repeater3"), Repeater).Items.Count = 0) Then
                e.Item.Visible = False
            End If
        End If
    End If
End Sub

根据评论,我还尝试了一个Prerender子。它提供了一个带有相同空的UL标签的站点地图列表。断点的使用没有确定为什么它不根据需要工作。

这是ASPX代码:

<asp:SiteMapDataSource ID="siteMapDataSource1" runat="server" ShowStartingNode="false" />
<asp:Repeater runat="server" ID="Repeater0" DataSourceID="SiteMapDataSource1">
    <HeaderTemplate>
        <ul>
            <li>
                <asp:HyperLink ID="HyperLink4" runat="server" NavigateUrl="~/index.aspx">Homepage</asp:HyperLink>
            </li>
    </HeaderTemplate>
    <ItemTemplate>
        <li>
            <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
            <asp:Repeater ID="Repeater1" runat="server" DataSource='<%# DirectCast(Container.DataItem, SiteMapNode).ChildNodes%>'>
                <HeaderTemplate>
                    <ul>
                </HeaderTemplate>
                <ItemTemplate>
                    <li>
                        <asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
                        <asp:Repeater ID="Repeater2" runat="server" DataSource='<%# DirectCast(Container.DataItem, SiteMapNode).ChildNodes%>'>
                            <HeaderTemplate>
                                <ul>
                            </HeaderTemplate>
                            <ItemTemplate>
                                <li>
                                    <asp:HyperLink ID="HyperLink3" runat="server" NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
                                    <asp:Repeater ID="Repeater3" runat="server" DataSource='<%# DirectCast(Container.DataItem, SiteMapNode).ChildNodes%>' OnPreRender="HideIfEmpty">
                                        <HeaderTemplate>
                                            <ul>
                                        </HeaderTemplate>
                                        <ItemTemplate>
                                            <li>
                                                <asp:HyperLink ID="HyperLink3" runat="server" NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
                                            </li>
                                        </ItemTemplate>
                                        <FooterTemplate>
                                            </ul>
                                        </FooterTemplate>
                                    </asp:Repeater>
                                </li>
                            </ItemTemplate>
                            <FooterTemplate>
                                </ul>
                            </FooterTemplate>
                        </asp:Repeater>
                    </li>
                </ItemTemplate>
                <FooterTemplate>
                    </ul>
                </FooterTemplate>
            </asp:Repeater>
        </li>
    </ItemTemplate>
    <FooterTemplate></ul></FooterTemplate>
</asp:Repeater>

这是渲染的html:

<ul id="menu_Main" class="sm sm-blue">
<li>
    <a id="Repeater0_HyperLink4" href="index.aspx">Homepage</a>
</li>
<li>
    <a id="Repeater0_HyperLink1_0">Data Manager Documents</a>
    <ul>
        <li>
            <a id="Repeater0_Repeater1_0_HyperLink2_0" href="/Data_Manager/Skill_Journal.aspx">Skill Journal</a>
            <ul>
            </ul>
        </li>
        <li>
            <a id="Repeater0_Repeater1_0_HyperLink2_1">Test Pages</a>
            <ul>
                <li>
                    <a id="Repeater0_Repeater1_0_Repeater2_1_HyperLink3_0" href="/Data_Manager/xslt_test.aspx">XSLT Test</a>
                    <ul>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</li>
<li>
    <a id="Repeater0_HyperLink1_1">Incident Report</a>
    <ul>
        <li>
            <a id="Repeater0_Repeater1_1_HyperLink2_0" href="http://wales:4885/IncidentReport/IncidentReport.aspx">Add/Edit/View</a>
            <ul>
            </ul>
        </li>
        <li>
            <a id="Repeater0_Repeater1_1_HyperLink2_1" href="http://wales:4885/IncidentReport/V1_History.aspx">Archive</a>
            <ul>
            </ul>
        </li>
    </ul>
</li>
<li>
    <a id="Repeater0_HyperLink1_2" href="/Ordering_Database/Ordering_Database.aspx">Ordering Database</a>
    <ul>
        <li>
            <a id="Repeater0_Repeater1_2_HyperLink2_0" href="/Ordering_Database/Reports.aspx">Reports</a>
            <ul>
            </ul>
        </li>
        <li>
            <a id="Repeater0_Repeater1_2_HyperLink2_1" href="/Ordering_Database/Stats.aspx">Stats</a>
            <ul>
            </ul>
        </li>
        <li>
            <a id="Repeater0_Repeater1_2_HyperLink2_2" href="/Ordering_Database/View_Items.aspx">View Items</a>
            <ul>
            </ul>
        </li>
        <li>
            <a id="Repeater0_Repeater1_2_HyperLink2_3" href="/Ordering_Database/Manage_Items.aspx">Manage Items</a>
            <ul>
            </ul>
        </li>
        <li>
            <a id="Repeater0_Repeater1_2_HyperLink2_4">Utility</a>
            <ul>
            </ul>
        </li>
    </ul>
</li>    

总而言之,将其渲染到嵌套的无序列表中的站点地图是正确的,但仍会产生空的UL标签,该标签应在服务器端删除。

对于此系统,这对我来说是真正的服务器端答案。

在脚本中:

<script>
Private Sub Hide_The_Orphans(ByVal sender As Object, ByVal e As RepeaterItemEventArgs)
    Dim rpt As Repeater = CType(sender, Repeater)
    If rpt IsNot Nothing Then
        If rpt.Items.Count = 0 Then
            rpt.Visible = False
        Else
            rpt.Visible = True
        End If
    End If
End Sub
</script>

在身体中(我还更改了ASP:超链接标签为<a>标签,以清理渲染的HTML中的所有这些超链接ID):

<nav>
                <asp:SiteMapDataSource ID="siteMapDataSource1" runat="server" ShowStartingNode="false" />
                <asp:Repeater runat="server" ID="Repeater0" DataSourceID="SiteMapDataSource1">
                    <HeaderTemplate>
                        <ul id="menu_Main" class="sm sm-blue">
                            <li>
                                <a href='<%# Page.ResolveClientUrl("~/index.aspx")%>'>Homepage</a>
                            </li>
                    </HeaderTemplate>
                    <ItemTemplate>
                        <li>
                            <a href='<%# Eval("Url") %>'><%# Eval("Title") %></a>
                            <asp:Repeater ID="Repeater1" runat="server" DataSource='<%# DirectCast(Container.DataItem, SiteMapNode).ChildNodes%>' OnItemDataBound="Hide_The_Orphans">
                                <HeaderTemplate>
                                    <ul>
                                </HeaderTemplate>
                                <ItemTemplate>
                                    <li>
                                        <a href='<%# Eval("Url") %>'><%# Eval("Title") %></a>
                                        <asp:Repeater ID="Repeater2" runat="server" DataSource='<%# DirectCast(Container.DataItem, SiteMapNode).ChildNodes%>' OnItemDataBound="Hide_The_Orphans">
                                            <HeaderTemplate>
                                                <ul>
                                            </HeaderTemplate>
                                            <ItemTemplate>
                                                <li>
                                                    <a href='<%# Eval("Url") %>'><%# Eval("Title") %></a>
                                                    <asp:Repeater ID="Repeater3" runat="server" DataSource='<%# DirectCast(Container.DataItem, SiteMapNode).ChildNodes%>' OnItemDataBound="Hide_The_Orphans">
                                                        <HeaderTemplate>
                                                            <ul>
                                                        </HeaderTemplate>
                                                        <ItemTemplate>
                                                            <li>
                                                                <a href='<%# Eval("Url") %>'><%# Eval("Title") %></a>
                                                            </li>
                                                        </ItemTemplate>
                                                        <FooterTemplate>
                                                            </ul>
                                                        </FooterTemplate>
                                                    </asp:Repeater>
                                                </li>
                                            </ItemTemplate>
                                            <FooterTemplate>
                                                </ul>
                                            </FooterTemplate>
                                        </asp:Repeater>
                                    </li>
                                </ItemTemplate>
                                <FooterTemplate>
                                    </ul>
                                </FooterTemplate>
                            </asp:Repeater>
                        </li>
                    </ItemTemplate>
                    <FooterTemplate></ul></FooterTemplate>
                </asp:Repeater>
            </nav>

并向自己证明这是一个真正的服务器端解决方案,这是从"查看源代码"中。

                        <ul id="menu_Main" class="sm sm-blue">
                            <li>
                                <a href='index.aspx'>Homepage</a>
                            </li>
                        <li>
                            <a href=''>Data Manager Documents</a>
                                    <ul>
                                    <li>
                                        <a href='/Data_Manager/Skill_Journal.aspx'>Skill Journal</a>
                                    </li>
                                    <li>
                                        <a href=''>Test Pages</a>
                                                <ul>
                                                <li>
                                                    <a href='/Data_Manager/.aspx'>Sitemap test</a>
                                                </li>
                                                <li>
                                                    <a href='/Data_Manager/xslt_test.aspx'>XSLT Test</a>
                                                </li>
                                                </ul>
                                    </li>
                                    </ul>
                        </li>
                        etc....

您看到空的HREF标签是因为这些特定节点更像文件夹容器,因此设计而不是错误。

这种方法的另一个加上的是,只有一个子可以被任何中继器使用,而不是像我之前尝试过的链接方法。

我想你几乎在那里。您的问题之一是,您正在尝试在Repeater0中找到Repeater3,而实际上它实际上在Repeater2中。您需要正确地沿着中继器的路线,找到正确的子ID。这是使用OnPreRender事件的示例,尽管您仍然可以使用类似逻辑使其适用于OnItemDataBound

<asp:Repeater runat="server" ID="Repeater0" DataSourceID="SiteMapDataSource1" OnPreRender="Repeater0_PreRender">

在此事件中,挖掘每个儿童中继器。如果儿童中继器没有物品,请隐藏整个中继器。您应该能够在此处从此代码中获得一个想法。但是,您可能会更好地递归地循环循环。

Protected Sub Repeater0_PreRender(ByVal sender As Object, ByVal e As EventArgs)
    Dim repeater0 As Repeater = sender
    If repeater0.Items.Count = 0 Then
        repeater0.Visible = False
    Else
        For Each repeater0Item As RepeaterItem In repeater0.Items
            If repeater0Item.ItemType = ListItemType.Item Then
                Dim repeater1 As Repeater = repeater0Item.FindControl("Repeater1")
                If repeater1.Items.Count = 0 Then
                    repeater1.Visible = False
                Else
                    For Each repeater1Item As RepeaterItem In repeater1.Items
                        If repeater1Item.ItemType = ListItemType.Item Then
                            Dim repeater2 As Repeater = repeater1Item.FindControl("Repeater2")
                            If repeater2.Items.Count = 0 Then
                                repeater2.Visible = False
                            Else
                                // so on and so forth
                            End If
                        End If
                    Next
                End If
            End If
        Next
    End If
End Sub

最新更新