Создание пользовательских клиентских элементов управления AJAX
Обновлен: Ноябрь 2007
В этом обзоре показано, как создать пользовательский клиентский элемент управления ASP.NET AJAX и использовать его на странице. Из этого обзора можно узнать, как выполнить следующие действия:
Использовать прототип шаблона разработки в ECMAScript (JavaScript) для определения класса элемента управления.
Зарегистрировать элемент управления, как класс, производный от базового класса Sys.UI.Control.
Инициализировать базовый класс Control и вызвать его методы.
Создавать пользовательские события, к которым разработчик страницы может выполнять привязку и которыми можно управлять.
Использовать клиентский элемент управления на странице и выполнять привязку к его событиям.
В обзоре приведен пример кода полного клиентского элемента управления, в ходе которого создается кнопка, реагирующая на наведение курсора.
Этот обзор посвящен клиентским элементам управления. Существует три типа объектов клиентских компонентов ASP.NET AJAX:
Невизуальные компоненты, производные от базового класса Sys.Component и не имеющие представления пользовательского интерфейса.
Поведения, производные от Sys.UI.Behavior.
Элементы управления, производные от Control.
В следующей таблице приведены различия между компонентами, поведениями и элементами управления.
Типы объектов клиентских компонентов |
Сводка |
---|---|
Компоненты |
|
Поведения |
|
Элементы управления |
|
Обязательные компоненты
Для выполнения примера клиентского элемента управления, приведенного в этом разделе, понадобится следующее:
- Веб-узел ASP.NET с поддержкой AJAX. Если такой узел уже имеется, и он настроен, то можно использовать его для этого примера. Дополнительные сведения о создании виртуального каталога или веб-узла см. в разделе Практическое руководство. Создание и настройка виртуальных каталогов в IIS 5.0 и 6.0.
Создание базовой функциональности пользовательского клиентского элемента управления ASP.NET AJAX
Клиентский элемент управления ASP.NET AJAX представляет элемент DOM как клиентский объект и расширяет представление разметки, или предоставляет элементу дополнительную функциональность. Например, клиентский элемент управления может расширить элемент HTML для реагирования на события мыши с помощью различных стилей CSS.
Клиентский элемент управления инкапсулирует код JavaScript, предназначенный для использования в различных приложениях. Будучи производным от базового класса Control, пользовательский элемент управления автоматически наследует многие встроенные, не зависящие от веб-обозревателя возможности, включая следующие:
Возможность добавлять и удалять обработчики событий для элементов DOM, связанных с элементом управления и для обработчиков событий самого элемента управления.
Автоматическая регистрация элемента управления как высвобождаемого объекта, реализующего интерфейс Sys.IDisposable.
Возможность вызывать события уведомления при изменении свойств.
Возможность выполнять пакетную обработку параметров свойства элемента управления. Это более эффективно с точки зрения размера сценария и времени обработки, чем обработка всей логики в методах доступа get и set для отдельного свойства.
Реализация клиентского элемента управления
Следующая таблица обобщает шаги, необходимые для реализации пользовательского клиентского элемента управления, производного от Control. Дополнительные сведения о каждом шаге приведены после таблицы.
Шаг |
Сводка |
---|---|
Определение класса клиентского элемента управления, используя прототип шаблона разработки. |
|
Инициализация базового экземпляра элемента управления Control и передача связанного элемента DOM как аргумента. |
|
Предоставление методов доступа к свойствам и при необходимости вызов события уведомления Sys.Component.propertyChanged. |
|
Переопределение метода Sys.UI.Control.initialize для инициализации свойств и прослушивателей событий. |
Если необходимо инициализировать свойства или прослушиватели событий для компонента или элементов DOM, переопределите метод initialize в прототипе компонента. В переопределенном методе выполните следующее:
|
Переопределение метода Sys.UI.Control.dispose для освобождения ресурсов, например, для удаления обработчиков событий DOM. |
Если имеются ресурсы, которые необходимо освободить до удаления элемента управления, переопределите метод dispose в прототипе компонента. В переопределенном методе выполните следующее:
|
Определение класса элемента управления при помощи прототипа шаблона разработки
Клиентский класс ASP.NET AJAX, включающий класс элемента управления, определяется в JavaScript при помощи прототипа шаблона разработки. Дополнительные сведения см. в разделе Создание клиентского класса компонентов с помощью модели прототипа.
Класс клиентских элементов управления должен быть производным от базового класса Control. Зарегистрируйте клиентский класс ASP.NET AJAX, как класс с клиентским приложением, используя метод Type.registerClass. Дополнительные сведения см. в разделе Метод Type.registerClass.
Инициализация базового класса
Базовый объект Control инициализируется в конструкторе элемента управления. В конструкторе элемента управления вызовите унаследованный метод initializeBase и передайте элемент DOM, полученный в аргументе конструктора, базовому классу. Обычно метод initializeBase вызывается до выполнения остального кода конструктора. При инициализации базового класса Control, его методы становятся доступны элементу управления, который автоматически регистрируется, как высвобождаемый объект с экземпляром Sys.Application. Дополнительные сведения см. в разделе Интерфейс Sys.IDisposable.
В следующем примере показана функция конструктора для элемента управления, производного от Control. Конструктор компонента вызывает унаследованный метод initializeBase.
Samples.SimpleControl = function(element)
{
Samples.SimpleControl.initializeBase(this, [element]);
}
Определение свойств и вызов уведомлений об изменении свойств
Определите свойства в клиентском классе элемента управления, которые разработчики страницы могут получать и задавать. Можно также вызвать события уведомления propertyChanged для этих свойств компонента. Разработчики страниц, использующие этот компонент, могут затем выполнить привязку к этим событиям. Компонент ASP.NET AJAX, производный от базового класса Component, Behavior или Control наследует метод Sys.Component.raisePropertyChanged, вызываемый для инициализации события propertyChanged. Дополнительные сведения см. в разделе Определение пользовательских свойств компонентов и создание событий PropertyChanged.
Инициализация свойств и прослушивателей событий
Если пользовательский элемент управления должен инициализировать свойства или прослушиватели событий, переопределите метод initialize в прототипе компонента. Клиентский элемент управления, производный от базового класса Control обычно привязывает обработчики к своим событиям элемента DOM и присваивает свойствам элемента DOM первоначальные значения. На последнем этапе вызовите базовый метод initialize для включения базового класса компонента, чтобы завершить инициализацию.
Освобождение ресурсов
Если пользовательский элемент управления должен освобождать ресурсы до своего удаления, переопределите метод dispose и освободите ресурсы в переопределенном методе. Это гарантирует немедленное освобождение ресурсов до удаления элемента управления. Освобождаемые ресурсы включают обработчики, используемые для привязки к событиям DOM. Убедитесь, что объект можно удалить, проверив, что удалены все возможные циклические ссылки между элементами DOM и объектом компонента. Дополнительные сведения см. в разделе Освобождение ресурсов компонентов.
Использование элемента управления на странице
Для использования пользовательского клиентского элемента управления на веб-странице ASP.NET сделайте следующее:
Зарегистрируйте библиотеку сценариев клиентского элемента управления на веб-странице.
Создайте экземпляр клиентского элемента управления.
В следующих подразделах подробно описаны этапы этой процедуры.
Регистрация библиотеки сценариев элемента управления на веб-странице
Сценарии, необходимые для клиентского элемента управления, можно зарегистрировать на странице с помощью элемента управления ScriptManager декларативно или программно.
В следующем примере показана декларативная разметка для элемента управления ScriptManager, регистрирующая сценарий элемента управления.
<form id="form1" runat="server">
<asp:ScriptManager runat="server" ID="ScriptManager01">
<scripts>
<asp:ScriptReference path="HoverButton.js" />
</scripts>
</asp:ScriptManager>
</form>
Элемент asp:ScriptManager содержит элемент asp:ScriptReference внутри узла scripts. Атрибут path элемента asp:ScriptReference ссылается на путь к файлу HoverButton.js, который определяет класс элемента управления. Дополнительные сведения см. в разделе Динамическое присваивание ссылок на сценарии и в общих сведениях о классе ScriptManager.
Примечание. |
---|
Все отдельные файлы библиотек, которые будут зарегистрированы элементом управления ScriptManager должны вызывать метод notifyScriptLoaded для уведомления приложения, что загрузка библиотеки завершена. Библиотеки, внедренные в сборку, чаще всего не должны вызывать этот метод. Дополнительные сведения см. в разделе Метод Sys.Application.notifyScriptLoaded. |
В качестве альтернативы регистрации файлов библиотек с использованием элемента управления ScriptManager, можно управлять клиентскими компонентами, используя пользовательский серверный элемент управления, который реализует интерфейс IScriptControl. Пользовательский серверный элемент управления может автоматически регистрировать требуемые библиотеки компонентов и выполнять декларативную разметку для настройки свойств компонента и привязок событий. Это упрощает для разработчика страницы использование собственного пользовательского элемента управления. Дополнительные сведения см. в общих сведениях о классе IScriptControl.
Создание экземпляра пользовательского элемента управления
Экземпляр пользовательского клиентского элемента управления создается путем вызова метода Sys.Component.create или псевдонима $create во время события Sys.Application.init. В следующей таблице описаны параметры, которые передаются методу $create при создании клиентского элемента управления.
Параметр |
Описание |
---|---|
type |
Тип компонента. |
properties |
Объект JSON, содержащий значение идентификатора компонента и, если необходимо, исходные пары "имя-значение" свойств. |
events |
Необязательный объект JSON, содержащий имя события и пары привязки "событие-обработчик". |
references |
Необязательный объект JSON, содержащий ссылки на связанные компоненты, переданные как пары "имя компонента-идентификатор". |
element |
Элемент DOM, который необходимо связать с элементом управления. |
В следующем примере показано, как создать экземпляр элемента управления, вызвав метод $create.
$create(Demo.HoverButton, {text: 'A HoverButton Control',element: {style: {fontWeight: "bold", borderWidth: "2px"}}}, {click: start, hover: doSomethingOnHover, unhover: doSomethingOnUnHover},null, $get('Button1'));
Дополнительные сведения см. в разделах Метод Sys.Component.create и Метод Sys.Component $create.
Создание пользовательского элемента управления HoverButton
В этом подразделе создается простой пользовательский клиентский элемент управления с именем HoverButton, расширяющий базовый класс Control, а затем этот элемент управления используется на странице. Элемент управления HoverButton перехватывает события click, focus, и mouseover связанного элемента HTML button. Он также обеспечивает элементы управления событиями, привязываемыми с помощью метода $create. Разработчик страницы, использующий элемент управления HoverButton, может выполнить привязку к событию hover этого элемента управления.
Создание кода для элемента управления HoverButton
В корневом каталоге веб-узла ASP.NET с поддержкой AJAX создайте файл с именем HoverButton.js.
Добавьте в этот файл следующий код:
Type.registerNamespace("Demo"); // Constructor Demo.HoverButton = function(element) { Demo.HoverButton.initializeBase(this, [element]); this._clickDelegate = null; this._hoverDelegate = null; this._unhoverDelegate = null; } Demo.HoverButton.prototype = { // text property accessors. get_text: function() { return this.get_element().innerHTML; }, set_text: function(value) { this.get_element().innerHTML = value; }, // Bind and unbind to click event. add_click: function(handler) { this.get_events().addHandler('click', handler); }, remove_click: function(handler) { this.get_events().removeHandler('click', handler); }, // Bind and unbind to hover event. add_hover: function(handler) { this.get_events().addHandler('hover', handler); }, remove_hover: function(handler) { this.get_events().removeHandler('hover', handler); }, // Bind and unbind to unhover event. add_unhover: function(handler) { this.get_events().addHandler('unhover', handler); }, remove_unhover: function(handler) { this.get_events().removeHandler('unhover', handler); }, // Release resources before control is disposed. dispose: function() { var element = this.get_element(); if (this._clickDelegate) { Sys.UI.DomEvent.removeHandler(element, 'click', this._clickDelegate); delete this._clickDelegate; } if (this._hoverDelegate) { Sys.UI.DomEvent.removeHandler(element, 'focus', this._hoverDelegate); Sys.UI.DomEvent.removeHandler(element, 'mouseover', this._hoverDelegate); delete this._hoverDelegate; } if (this._unhoverDelegate) { Sys.UI.DomEvent.removeHandler(element, 'blur', this._unhoverDelegate); Sys.UI.DomEvent.removeHandler(element, 'mouseout', this._unhoverDelegate); delete this._unhoverDelegate; } Demo.HoverButton.callBaseMethod(this, 'dispose'); }, initialize: function() { var element = this.get_element(); if (!element.tabIndex) element.tabIndex = 0; if (this._clickDelegate === null) { this._clickDelegate = Function.createDelegate(this, this._clickHandler); } Sys.UI.DomEvent.addHandler(element, 'click', this._clickDelegate); if (this._hoverDelegate === null) { this._hoverDelegate = Function.createDelegate(this, this._hoverHandler); } Sys.UI.DomEvent.addHandler(element, 'mouseover', this._hoverDelegate); Sys.UI.DomEvent.addHandler(element, 'focus', this._hoverDelegate); if (this._unhoverDelegate === null) { this._unhoverDelegate = Function.createDelegate(this, this._unhoverHandler); } Sys.UI.DomEvent.addHandler(element, 'mouseout', this._unhoverDelegate); Sys.UI.DomEvent.addHandler(element, 'blur', this._unhoverDelegate); Demo.HoverButton.callBaseMethod(this, 'initialize'); }, _clickHandler: function(event) { var h = this.get_events().getHandler('click'); if (h) h(this, Sys.EventArgs.Empty); }, _hoverHandler: function(event) { var h = this.get_events().getHandler('hover'); if (h) h(this, Sys.EventArgs.Empty); }, _unhoverHandler: function(event) { var h = this.get_events().getHandler('unhover'); if (h) h(this, Sys.EventArgs.Empty); } } Demo.HoverButton.registerClass('Demo.HoverButton', Sys.UI.Control); // Since this script is not loaded by System.Web.Handlers.ScriptResourceHandler // invoke Sys.Application.notifyScriptLoaded to notify ScriptManager // that this is the end of the script. if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
Рассмотрение кода
Этот код регистрирует пространство имен Demo, вызывая метод Type.registerNamespace. Конструктор вызывает унаследованный метод initializeBase, в результате чего становятся доступными методы базового класса Control. Инициализированный базовый класс в свою очередь регистрирует экземпляр Demo.HoverButton в клиентском приложении в виде высвобождаемого объекта.
В прототипе код объявляет открытые события click, hover и unhover. Разработчик страницы может добавлять и удалять обработчики, ожидающие эти события. Эти методы в свою очередь добавляют и удаляют указанный обработчик через коллекцию обработчика событий элемента управления. Добавлять обработчики в класс элемента управления или удалять их из него можно через объект элемента управления Sys.EventHandlerList. Объект EventHandlerList содержит коллекцию обработчиков событий элемента управления через унаследованное свойство Sys.Component.events. В этом примере код вызывает методы Sys.EventHandlerList.addHandler и Sys.EventHandlerList.removeHandler возвращаемого объекта EventHandlerList для добавления или удаления обработчиков.
Класс HoverButton переопределяет базовый метод dispose для безопасного удаления ресурсов элемента управления (таких как обработчики событий DOM) до удаления элемента управления. И, наконец, код вызывает базовый метод dispose, чтобы позволить приложению освободить элемент управления.
Использование элемента управления HoverButton на веб-странице
В этом разделе показано, как создать экземпляр элемента управления, используя клиентский сценарий на веб-странице.
Создание страницы для использования элемента управления HoverButton
В корневом каталоге приложения, в котором находится файл HoverButton.js, создайте файл с именем DemoHoverButton.aspx.
В этот файл добавьте следующую разметку и код:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <style type="text/css"> button {border: solid 1px black} #HoverLabel {color: blue} </style> <title>Control Demo</title> </head> <body> <form id="form1" runat="server"> <div id="ResultDisplay"></div> <asp:ScriptManager runat="server" ID="ScriptManager01"> <scripts> <asp:ScriptReference Path="HoverButton.js" /> </scripts> </asp:ScriptManager> <script type="text/javascript"> var app = Sys.Application; app.add_init(applicationInitHandler); function applicationInitHandler(sender, args) { $create(Demo.HoverButton, {text: 'A HoverButton Control',element: {style: {fontWeight: "bold", borderWidth: "2px"}}}, {click: start, hover: doSomethingOnHover, unhover: doSomethingOnUnHover},null, $get('Button1')); } function doSomethingOnHover(sender, args) { hoverMessage = "The mouse is over the button." $get('HoverLabel').innerHTML = hoverMessage; } function doSomethingOnUnHover(sender, args) { $get('HoverLabel').innerHTML = ""; } function start(sender, args) { alert("The start function handled the HoverButton click event."); } </script> <button type="button" id="Button1"></button> <div id="HoverLabel"></div> </form> </body> </html>
Рассмотрение кода
Файл DemoHoverButton.aspx является веб-страницей ASP.NET, содержащей пользовательский элемент управления. На странице, функции, привязанные к пользовательскому элементу управления, определяются в элементе script. В обработчике событий Sys.Application.init экземпляр элемента управления HoverButton создается в клиентском сценарии путем вызова метода $create. Код передает методу $create следующие аргументы:
Аргумент type содержит созданный ранее класс Demo.HoverButton.
Аргумент properties содержит объект JSON, который содержит требуемое значение идентификатора элемента управления, за которым идут пары "имя-значение" свойства, указывающие имена свойств с начальными значениями.
Аргумент events содержит объект, содержащий пары имен событий с их обработчиками.
В элементе управления ScriptManager атрибут path узла asp:ScriptReference ссылается на путь к файлу HoverButton.js, который определяет класс элементов управления Demo.HoverButton.
Настройка обработчиков событий элемента DOM и обработчиков событий компонента
Функциональность AJAX в ASP.NET включает классы, обеспечивающие стандартизированное управление событиями для компонентов и элементов DOM. Управлять событиями своих элементов управления можно при помощи членов класса Sys.EventHandlerList, таких как addHandler и removeHandler. Дополнительные сведения см. в общих сведениях о классе Sys.EventHandlerList.
Управлять обработчиками событий для элементов DOM или для событий объекта window можно при помощи статических методов класса Sys.UI.DomEvent: addHandler или removeHandler. Дополнительные сведения см. в общих сведениях о классе Sys.UI.DomEvent.
Доступ к свойствам элемента DOM
Класс Sys.UI.DomElement содержит члены, которые позволяют добавлять, удалять и включать или выключать ассоциации класса CSS для клиентских элементов управления и элементов. Эти члены также обеспечивают стандартизированный доступ к свойствам элемента DOM. Дополнительные сведения см. в разделе Класс Sys.UI.DomElement.
См. также
Задачи
Создание настраиваемых невизуальных клиентских компонентов
Динамическое присваивание ссылок на сценарии
Основные понятия
Использование элемента управления UpdatePanel ASP.NET с элементами управления с привязкой к данным
Работа с событиями класса PageRequestManager