Статьи

Атлас: UpdatePanel + Template = Really Darned Kewl

Должен сказать, что ASP.NET Atlas , бесплатная Ajax-инфраструктура Microsoft, довольно крутая. Моя любимая особенность — это то, что она позволяет мне, руководителю C # из Javascript, создавать действительно приятные приложения Ajaxy, не выходя из моей зоны комфорта на стороне сервера. Все, что нужно было сделать, — это написать приложение, чтобы оно работало в рамках обычного жизненного цикла ASP.NET, событий и параметров. Затем добавьте туда Atlas: UpdatePanels и дайте фреймворку сделать свое дело.

Или я так думал. Я попытался включить эти UpdatePanels в шаблонный элемент управления, такой как Repeater. И Атлас идет бум. Теперь это не было непреодолимой проблемой. Можно всегда окружить весь ретранслятор в панели обновления. Или вернитесь к классическим методам, не относящимся к Atlas. Или изучите Javascript и создайте свой собственный сантехник. Ни один из которых не является очень привлекательным вариантом.

Удобно, что команда Atlas также видела в этом исправленную проблему. И 30 июня они выпустили еще одну ОСАГО, которая в июне называется «Атлас» — «Атлас». В нем есть ряд твиков и исправлений, один из которых близок и дорог мне моему сердцу:

UpdatePanels можно динамически добавлять на страницу в течение жизненного цикла страницы, включая UpdatePanels внутри шаблонов. UpdatePanels теперь также работают внутри WebParts, а WebParts могут быть внутри UpdatePanels.

Итак, я разработал небольшую демонстрацию того, насколько удобна новая функциональность. И, судя по всему, какой классный Атлас может быть.

Сценарий: у вас есть список контактов с четырьмя полями: Id, FirstName, LastName и Email. Требуется, чтобы никто не видел адрес электронной почты, не щелкнув ссылку, указывающую приложению показать этот адрес. Пример набора данных в Xml опубликован в конце этого сообщения для справки.

Теперь можно пойти после этого двумя способами. Во-первых, можно рассчитывать на традиционную обратную передачу и полное обновление страницы. Или можно принять Web 2.0 и включить свой Атлас. Действительно приятная вещь заключается в том, что оба метода могут использовать один и тот же файл codebehind [хорошо, не совсем — вам нужно изменить имя класса, чтобы оно соответствовало вашей ссылке CodeFile в файле .aspx]. Это выглядит так:

private DataSet peopleDs; protected DataTable People { get { if (peopleDs == null) { peopleDs = new DataSet(); peopleDs.ReadXml(Server.MapPath("~/App_Data/Data.xml")); } return peopleDs.Tables[0]; } } protected void Page_Load(object sender, EventArgs e) { if (!this.IsPostBack) { this.DataBind(); } } protected void ItemButtonClicked(object sender, EventArgs e) { Control csender = (Control)sender; Literal litid = (Literal)csender.NamingContainer.FindControl("PersonId"); string email=getEmailAddress(litid.Text); HyperLink link = (HyperLink)csender.NamingContainer.FindControl("EmailAddress"); link.NavigateUrl = string.Format("mailto:{0}", email); link.Text = email; csender.Visible = false; link.Visible = true; } private string getEmailAddress(string id) { string ret = "NO EMAIL"; DataRow[] match = People.Select("Id=" + id); if (match.Length > 0) { ret = (string)match[0]["Email"]; } return ret; } 

Теперь традиционный метод отображения этого очень прост. Смотрите ниже пример:

<form id="form1" runat="server"> <div> <asp:Repeater runat="server" ID="PersonRepeater" DataSource="<%# People %>"> <ItemTemplate> <div style="border: solid 1px black; padding: 5px"> <asp:Literal ID="PersonId" runat="server" Visible="false" Text='<%# DataBinder.Eval(Container.DataItem, "Id") %>' /> First Name: <%# DataBinder.Eval(Container.DataItem, "FirstName") %> <br /> Last Name: <%# DataBinder.Eval(Container.DataItem, "LastName") %> <br /> <asp:LinkButton runat="server" ID="ShowEmail" OnClick="ItemButtonClicked" Text="Show Contact Info" /> <asp:HyperLink ID="EmailAddress" runat="server" Visible="False" /> </div> </ItemTemplate> </asp:Repeater> </div> </form>
<form id="form1" runat="server"> <div> <asp:Repeater runat="server" ID="PersonRepeater" DataSource="<%# People %>"> <ItemTemplate> <div style="border: solid 1px black; padding: 5px"> <asp:Literal ID="PersonId" runat="server" Visible="false" Text='<%# DataBinder.Eval(Container.DataItem, "Id") %>' /> First Name: <%# DataBinder.Eval(Container.DataItem, "FirstName") %> <br /> Last Name: <%# DataBinder.Eval(Container.DataItem, "LastName") %> <br /> <asp:LinkButton runat="server" ID="ShowEmail" OnClick="ItemButtonClicked" Text="Show Contact Info" /> <asp:HyperLink ID="EmailAddress" runat="server" Visible="False" /> </div> </ItemTemplate> </asp:Repeater> </div> </form> 

Но что, если ваш клиент потребовал, чтобы на его сайте была включена поддержка Ajax? Это очень просто — просто добавьте немного атласа и панель обновлений. О, и не забудьте Atlas: UpdateProgress, чтобы вы могли оправдать счет.

<form id="form1" runat="server"> <atlas:ScriptManager ID="TheScriptManager" runat="server" EnablePartialRendering="true" /> <div> <atlas:UpdateProgress ID="UpdateProgress" runat="server"> <ProgressTemplate> <span style="position: absolute; top: 0; left: 0; height: 15px; color: White; background-color: Red; width: 50px">UPDATING</span> </ProgressTemplate> </atlas:UpdateProgress> <asp:Repeater runat="server" ID="PersonRepeater" DataSource="<%# People %>"> <ItemTemplate> <div style="border: solid 1px black; padding: 5px"> <asp:Literal ID="PersonId" runat="server" Visible="false" Text='<%# DataBinder.Eval(Container.DataItem, "Id") %>' /> First Name: <%# DataBinder.Eval(Container.DataItem, "FirstName") %> <br /> Last Name: <%# DataBinder.Eval(Container.DataItem, "LastName") %> <br /> <atlas:UpdatePanel ID="RepeaterUpdatePanel" runat="Server" Mode="conditional"> <Triggers> <atlas:ControlEventTrigger ControlID="ShowEmail" EventName="Click" /> </Triggers> <ContentTemplate> <asp:LinkButton runat="server" ID="ShowEmail" OnClick="ItemButtonClicked" Text="Show Contact Info" /> <asp:HyperLink ID="EmailAddress" runat="server" Visible="False" /> </ContentTemplate> </atlas:UpdatePanel> </div> </ItemTemplate> </asp:Repeater> </div> </form>
<form id="form1" runat="server"> <atlas:ScriptManager ID="TheScriptManager" runat="server" EnablePartialRendering="true" /> <div> <atlas:UpdateProgress ID="UpdateProgress" runat="server"> <ProgressTemplate> <span style="position: absolute; top: 0; left: 0; height: 15px; color: White; background-color: Red; width: 50px">UPDATING</span> </ProgressTemplate> </atlas:UpdateProgress> <asp:Repeater runat="server" ID="PersonRepeater" DataSource="<%# People %>"> <ItemTemplate> <div style="border: solid 1px black; padding: 5px"> <asp:Literal ID="PersonId" runat="server" Visible="false" Text='<%# DataBinder.Eval(Container.DataItem, "Id") %>' /> First Name: <%# DataBinder.Eval(Container.DataItem, "FirstName") %> <br /> Last Name: <%# DataBinder.Eval(Container.DataItem, "LastName") %> <br /> <atlas:UpdatePanel ID="RepeaterUpdatePanel" runat="Server" Mode="conditional"> <Triggers> <atlas:ControlEventTrigger ControlID="ShowEmail" EventName="Click" /> </Triggers> <ContentTemplate> <asp:LinkButton runat="server" ID="ShowEmail" OnClick="ItemButtonClicked" Text="Show Contact Info" /> <asp:HyperLink ID="EmailAddress" runat="server" Visible="False" /> </ContentTemplate> </atlas:UpdatePanel> </div> </ItemTemplate> </asp:Repeater> </div> </form> 

Первое, на что стоит обратить внимание, это новые теги Atlas: SomeControlName. ScriptManager запускает шоу; требуется «Атлас включить» страницу. Элемент управления UpdateProgress представляет собой визуальный эффект — он позволяет сообщить пользователю, что выполняется обновление, очень похоже на «ЗАГРУЗКУ», которую можно увидеть в правом верхнем углу Gmail.

Это приводит нас к Atlas: UpdatePanel. Это очень удобный элемент управления, позволяющий частично отображать страницу и запускать обновления на основе зарегистрированных событий. В этом случае мы предоставляем шаблон, содержащий наш LinkButton и HyperLink, с которым он взаимодействует, и один Trigger. Этот триггер используется Atlas для запуска обновления. И панель может иметь несколько триггеров. В нашем случае нам нужен был только один — событие click нашего LinkButton. И, как показывает пример кода, это событие ведет себя почти идентично стандартному полностраничному постбеку.

От нуля до Web 2.0 за 6,4 минуты. Без написания одного символа Javascript и без изменения вашего C #.

Приложение: XML-файл

<Persons> <Person> <Id>1</Id> <FirstName>Donald</FirstName> <LastName>Duck</LastName> <Email>[email protected]</Email> </Person> <Person> <Id>2</Id> <FirstName>Mickey</FirstName> <LastName>Mouse</LastName> <Email>[email protected]</Email> </Person> <Person> <Id>3</Id> <FirstName>Peter</FirstName> <LastName>Pan</LastName> <Email>[email protected]</Email> </Person> <Person> <Id>4</Id> <FirstName>Captain</FirstName> <LastName>Hook</LastName> <Email>[email protected]</Email> </Person> </Persons>
<Persons> <Person> <Id>1</Id> <FirstName>Donald</FirstName> <LastName>Duck</LastName> <Email>[email protected]</Email> </Person> <Person> <Id>2</Id> <FirstName>Mickey</FirstName> <LastName>Mouse</LastName> <Email>[email protected]</Email> </Person> <Person> <Id>3</Id> <FirstName>Peter</FirstName> <LastName>Pan</LastName> <Email>[email protected]</Email> </Person> <Person> <Id>4</Id> <FirstName>Captain</FirstName> <LastName>Hook</LastName> <Email>[email protected]</Email> </Person> </Persons>