Четкое понимание событийной модели - это самое главное и основное умение которым вы должны обладать при использовании классической модели ASP.NET ( WebForms). Это скелет, устав, 10 заповедей - назовите это как хотите. Без знания и понимания данной модели создание эффективных веб-приложений невозможно.
Ниже два примера, показывающих как незнание событийной модели может испортить вам жизнь. Суть примера такова - на странице находится ListView c с данными, и кнопка по счелчку на которую переходим на другую страницу. В обоих случаях - пользователь увидит наполненный ListView и перейдетнастраницу, но есть ньансы...
Main.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="main.aspx.vb" Inherits="main" %>
<html>
<head runat="server"><title></title></head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Button" />
<asp:ListView ID="ListView1" runat="server">
<LayoutTemplate>
<ul>
<asp:PlaceHolder runat="server" ID="itemPlaceholder" />
</ul>
</LayoutTemplate>
<ItemTemplate>
<li>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</li>
</ItemTemplate>
</asp:ListView>
</div>
</form>
</body>
</html>
Main.aspx.vb (вариант №1)
Partial Class main
Inherits System.Web.UI.Page
'биндинг ListView на Page_Load
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
ListView1.DataSource = GetData()
ListView1.DataBind()
End Sub
'биндинг каждого элемента ListView
Protected Sub ListView1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewItemEventArgs) Handles ListView1.ItemDataBound
CType(e.Item.FindControl("Label1"), Label).Text = CType(CType(e.Item, ListViewDataItem).DataItem, String)
End Sub
'переход на эту же страницу
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Button1.Click
Response.Redirect("states.aspx", True)
End Sub
'Функция для создания коллекции необходимой для наполнения ListView
Public Function GetData() As List(Of String)
Dim result As New List(Of String)
For i As Integer = 0 To 100
Dim labelName As String = "Label #" & i.ToString
result.Add(labelName)
Next
Return result
End Function
End Class
Main.aspx.vb (вариант №2)
Partial Class main
Inherits System.Web.UI.Page
'биндинг ListView на Page_PreRender
Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.PreRender
ListView1.DataSource = GetData()
ListView1.DataBind()
End Sub
'биндинг каждого элемента ListView
Protected Sub ListView1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewItemEventArgs) Handles ListView1.ItemDataBound
CType(e.Item.FindControl("Label1"), Label).Text = CType(CType(e.Item, ListViewDataItem).DataItem, String)
End Sub
'переход на эту же страницу
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Button1.Click
Response.Redirect("main.aspx", True)
End Sub
'Функция для создания коллекции необходимой для наполнения ListView
Public Function GetData() As List(Of String)
Dim result As New List(Of String)
For i As Integer = 0 To 100
Dim labelName As String = "Label #" & i.ToString
result.Add(labelName)
Next
Return result
End Function
End Class
Разбор Полетов
В обоих случаях ListView будет наполнен и пользователь сможет перейти на другую страницу ( в нашем случае - та же самая страница). Теперь важно понимать событийную модель, чтобы увидеть в чем проблема для варианта №1.
В первом варианте биндинг ListView проводится на обработчике события Page_Load.
Переход на страницу осуществляется на событии кнопки Click.
Что происходит по счелчку на кнопку? По счелчку страница уходит на сервер, где начинается ее обработка. Согласно событийной модели, сначала отработается событие Load ( а вместе с этим выполнится код описанный в обработчике этого события Page_Load). Только после этого отработается отложенное событие, которым является Click нашей кнопки. И только после этого произойдет переход на другую страницу.
Таким образом биндинг ListView будет происходить все время.
А если взять ситуацию, когда наполнение коллекции данных для ListView включает в себя "тяжелые запросы" - это может превратиться для пользователя в тихий ужас. Хочет он перейти на другую страницу и ждет от этого действия мгновенной реакции - а ему вместо этого каждый раз вычитываются данные для ListView, которые ему уже не нужны.
Во втором случае биндинг ListView проводится на обработчике события Page_PreRender
Переход на страницу осуществляется на событии кнопки Click.
Во втором случае все проиходит нормально. Событие PreRender возникает после обработки отложенных событий ( событие Click нашей кнопки). Таким образом, биндинг ListView не будет происходить лишний раз. По счелчку на кнопку пользователь сразу перейдет на страницу.
Понимание событийной модели очень важно.
Ссылка на МSDNовский ресурс который замечательно описывает событийную модель страницы. >>
Комментариев нет:
Отправить комментарий