Вопрос или проблема
У меня есть главная страница с несколькими меню, которые имеют подменю и, наконец, элементы меню. Я хотел бы пройти по каждому li (желательно по классу=”menu-item”) на стороне сервера, чтобы установить их видимость на false, а затем показывать их по одному в зависимости от прав пользователя. Структура в общем виде такая:
<ul id="Menu1">
<li id="Menu1Opt1">
<ul id="SubMenu1">
<li id="SubMenu1Item1" class="menu-item" runat="server">
<li id="SubMenu1Item2" class="menu-item" runat="server">
</ul>
</li>
<li id="Menu1Opt2">
<ul id="SubMenu2">
<li id="SubMenu2Item1" class="menu-item" runat="server">
<li id="SubMenu2Item2" class="menu-item" runat="server">
</ul>
</li>
</ul>
Я хотел бы иметь возможность сделать что-то вроде этого:
Private sub Boop()
For Each ele As HtmlElement In Master GetElementsByClassName("menu-item")
ele.visible = False
Next
End Sub
Я даже не уверен, нужно ли указывать ‘Master’, потому что это происходит в коде за главной страницей.
Я могу сделать:
SubMenu1Item1.visible = False
но их много, и мне бы гораздо больше понравилось пройти по ним, чтобы облегчить запись и поддержку.
Как лучше всего это осуществить? Спасибо.
Ответ или решение
Чтобы выполнить итерацию по элементам <li>
с классом menu-item
на серверной стороне с использованием VB.Net в мастер-странице ASP.NET, вы можете воспользоваться классом HtmlGenericControl
, чтобы динамически управлять видимостью элементов. В этом ответе мы рассмотрим, как это сделать шаг за шагом.
Шаг 1: Подготовка структуры
Предположим, у вас есть следующая структура меню в мастер-странице:
<ul id="Menu1">
<li id="Menu1Opt1">
<ul id="SubMenu1">
<li id="SubMenu1Item1" class="menu-item" runat="server">SubMenu Item 1</li>
<li id="SubMenu1Item2" class="menu-item" runat="server">SubMenu Item 2</li>
</ul>
</li>
<li id="Menu1Opt2">
<ul id="SubMenu2">
<li id="SubMenu2Item1" class="menu-item" runat="server">SubMenu Item 1</li>
<li id="SubMenu2Item2" class="menu-item" runat="server">SubMenu Item 2</li>
</ul>
</li>
</ul>
Каждый элемент <li>
имеет атрибут runat="server"
, что позволяет обращаться к ним из кода на сервере.
Шаг 2: Создание метода в коде за мастер-страницей
Вы должны создать метод, который будет скрывать все элементы с классом menu-item
. Это можно сделать с помощью коллекции контролов и метода FindControl
.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
If Not IsPostBack Then
HideMenuItems()
End If
End Sub
Private Sub HideMenuItems()
For Each item As Control In FindControlsRecursive(Me)
If TypeOf item Is HtmlGenericControl Then
Dim li As HtmlGenericControl = CType(item, HtmlGenericControl)
If li.Attributes("class") IsNot Nothing AndAlso li.Attributes("class").Contains("menu-item") Then
li.Visible = False
End If
End If
Next
End Sub
Private Function FindControlsRecursive(ByVal root As Control) As IEnumerable(Of Control)
Dim controls As New List(Of Control)
For Each control As Control In root.Controls
controls.Add(control)
controls.AddRange(FindControlsRecursive(control))
Next
Return controls
End Function
Шаг 3: Объяснение кода
-
Page_Load: Метод
Page_Load
отвечает за вызовHideMenuItems()
только в первый раз, когда загружается страница (не при постбэках). -
HideMenuItems: Этот метод проходит через все контролы на странице с помощью вспомогательной функции
FindControlsRecursive()
. Если контрол являетсяHtmlGenericControl
и имеет классmenu-item
, его видимость устанавливается вFalse
. -
FindControlsRecursive: Эта функция рекурсивно проходит через все дочерние контролы, добавляя их в список, который будет возвращен.
Шаг 4: Настройка видимости на основе прав пользователя
После того как вы скрыли все элементы, вы можете настроить их видимость в зависимости от прав пользователя. Это можно сделать путем добавления логики после вызова HideMenuItems()
, где вы определяете, какие элементы сделать видимыми на основе своих условий.
Private Sub SetMenuItemVisibility(ByVal userPermissions As List(Of String))
' Пример: userPermissions может содержать ID разрешенных элементов
For Each item As Control In FindControlsRecursive(Me)
If TypeOf item Is HtmlGenericControl Then
Dim li As HtmlGenericControl = CType(item, HtmlGenericControl)
If li.Attributes("class") IsNot Nothing AndAlso li.Attributes("class").Contains("menu-item") Then
If userPermissions.Contains(li.ID) Then
li.Visible = True
End If
End If
End If
Next
End Sub
Заключение
Используя описанный подход, вы можете эффективно управлять видимостью элементов меню на ASP.NET мастер-странице с помощью VB.Net. Этот метод не только уменьшает объем кода, но и делает его более удобным для обслуживания и модификации. Убедитесь, что у вас есть корректная логика управления правами доступа для обеспечения безопасности вашего приложения.